]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/53650 (large array causes huge memory use)
authorJason Merrill <jason@redhat.com>
Thu, 3 Jan 2013 16:51:41 +0000 (11:51 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 3 Jan 2013 16:51:41 +0000 (11:51 -0500)
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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/testsuite/g++.dg/init/array34.C [new file with mode: 0644]

index 1690aebbfc91fe38e49ef2a0f707053a66ac6d9d..e349084e499d081c165539d81e658382ce2c3f92 100644 (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
index ad39637c8b7a4b1b1b377b95a00831c43e6d58aa..1466c4b4db867f91d061649fb0203fe5f36313d7 100644 (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
index 465fa0f78efb6a2e51bd0551f60799359d245e83..810df7de29cd21e6076a646cf0605eb911a2194b 100644 (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);
index 52ceefce03b4596beef8c831f09c96cd0abfcda5..5c268b10b7f5851f505ea5c501f9b1ec905f67e3 100644 (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);
 
index 6edc0a5df8b036f358236d42a072036a07d961f7..2ee2473925907bd714154aaafe6a3a828f372557 100644 (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);
diff --git a/gcc/testsuite/g++.dg/init/array34.C b/gcc/testsuite/g++.dg/init/array34.C
new file mode 100644 (file)
index 0000000..c5f608b
--- /dev/null
@@ -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;
+}