re PR c++/53650 (large array causes huge memory use)

PR c++/53650
	* call.c (type_has_extended_temps): New.
	* cp-tree.h: Declare it.
	* decl.c (check_initializer): Use build_aggr_init for arrays
	if it is false.
	* init.c (build_vec_init): Avoid mixed signed/unsigned arithmetic.

From-SVN: r194860
This commit is contained in:
Jason Merrill 2013-01-03 11:51:41 -05:00 committed by Jason Merrill
parent bcf1ef0055
commit 99c4346a66
6 changed files with 51 additions and 2 deletions

View File

@ -1,3 +1,12 @@
2013-01-03 Jason Merrill <jason@redhat.com>
PR c++/53650
* call.c (type_has_extended_temps): New.
* cp-tree.h: Declare it.
* decl.c (check_initializer): Use build_aggr_init for arrays
if it is false.
* init.c (build_vec_init): Avoid mixed signed/unsigned arithmetic.
2013-01-02 Jason Merrill <jason@redhat.com>
PR c++/54325

View File

@ -9234,6 +9234,28 @@ extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups)
return init;
}
/* Returns true iff an initializer for TYPE could contain temporaries that
need to be extended because they are bound to references or
std::initializer_list. */
bool
type_has_extended_temps (tree type)
{
type = strip_array_types (type);
if (TREE_CODE (type) == REFERENCE_TYPE)
return true;
if (CLASS_TYPE_P (type))
{
if (is_std_init_list (type))
return true;
for (tree f = next_initializable_field (TYPE_FIELDS (type));
f; f = next_initializable_field (DECL_CHAIN (f)))
if (type_has_extended_temps (TREE_TYPE (f)))
return true;
}
return false;
}
/* Returns true iff TYPE is some variant of std::initializer_list. */
bool

View File

@ -4952,6 +4952,7 @@ extern tree initialize_reference (tree, tree, int,
tsubst_flags_t);
extern tree extend_ref_init_temps (tree, tree, vec<tree, va_gc>**);
extern tree make_temporary_var_for_ref_to_temp (tree, tree);
extern bool type_has_extended_temps (tree);
extern tree strip_top_quals (tree);
extern bool reference_related_p (tree, tree);
extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t);

View File

@ -5657,7 +5657,9 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
if ((type_build_ctor_call (type) || CLASS_TYPE_P (type))
&& !(flags & LOOKUP_ALREADY_DIGESTED)
&& !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
&& CP_AGGREGATE_TYPE_P (type)))
&& CP_AGGREGATE_TYPE_P (type)
&& (CLASS_TYPE_P (type)
|| type_has_extended_temps (type))))
{
init_code = build_aggr_init_full_exprs (decl, init, flags);

View File

@ -3637,7 +3637,9 @@ build_vec_init (tree base, tree maxindex, tree init,
if (TREE_CODE (type) == ARRAY_TYPE)
m = cp_build_binary_op (input_location,
MULT_EXPR, m,
array_type_nelts_total (type),
/* Avoid mixing signed and unsigned. */
convert (TREE_TYPE (m),
array_type_nelts_total (type)),
complain);
finish_cleanup_try_block (try_block);

View File

@ -0,0 +1,13 @@
// PR c++/53650
// We should loop over array inits if they don't involve temporaries
// that need extending.
// { dg-final { scan-assembler-times "_ZN5ClassC1Ev" 1 } }
struct Class {
Class();
};
int main() {
Class table [10] = {};
return 0;
}