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: r195380
This commit is contained in:
Jason Merrill 2013-01-22 11:28:58 -05:00 committed by Jason Merrill
parent c2a701ec31
commit e5ec225183
6 changed files with 51 additions and 2 deletions

View File

@ -1,5 +1,12 @@
2013-01-22 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.
PR c++/56071
* pt.c (maybe_instantiate_noexcept): Don't defer access checks.

View File

@ -8835,6 +8835,28 @@ extend_ref_init_temps (tree decl, tree init, VEC(tree,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

@ -4889,6 +4889,7 @@ extern tree initialize_reference (tree, tree, int,
tsubst_flags_t);
extern tree extend_ref_init_temps (tree, tree, VEC(tree,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

@ -5556,7 +5556,9 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,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

@ -3501,7 +3501,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),
/* Force signed arithmetic. */
convert (TREE_TYPE (m),
array_type_nelts_total (type)),
complain);
finish_cleanup_try_block (try_block);

View File

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