diff options
author | Jason Merrill <jason@redhat.com> | 2013-01-03 11:51:41 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-01-03 11:51:41 -0500 |
commit | 99c4346a66ed358d49097bb14d9b5cf27528d58e (patch) | |
tree | d08a78ce2e0359cdea2dda0c9c83749417566ec0 | |
parent | bcf1ef005542850e15a6bbb9a148a9b87a693c33 (diff) | |
download | gcc-99c4346a66ed358d49097bb14d9b5cf27528d58e.zip gcc-99c4346a66ed358d49097bb14d9b5cf27528d58e.tar.gz gcc-99c4346a66ed358d49097bb14d9b5cf27528d58e.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/call.c | 22 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/array34.C | 13 |
6 files changed, 51 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1690aeb..e349084 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ad39637..1466c4b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 465fa0f..810df7d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 52ceefc..5c268b1 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 6edc0a5..2ee2473 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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); diff --git a/gcc/testsuite/g++.dg/init/array34.C b/gcc/testsuite/g++.dg/init/array34.C new file mode 100644 index 0000000..c5f608b --- /dev/null +++ b/gcc/testsuite/g++.dg/init/array34.C @@ -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; +} |