re PR c++/57402 (ICE: in make_decl_rtl, at varasm.c:1147 when initializing variable...
authorJason Merrill <jason@redhat.com>
Sat, 13 Jul 2013 23:10:24 +0000 (19:10 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 13 Jul 2013 23:10:24 +0000 (19:10 -0400)
PR c++/57402
* init.c (build_vec_init): Use {} for arrays of class type.
(build_vec_delete): Don't take the address of the array.

From-SVN: r200939

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/g++.dg/cpp0x/defaulted45.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp1y/vla-initlist1.C [new file with mode: 0644]

index 1bf287aecee60ccbb39a99eb608a6377696306e2..4e4663058298dfdeb93225eb0c91ad6f0ef78991 100644 (file)
@@ -1,5 +1,9 @@
 2013-07-13  Jason Merrill  <jason@redhat.com>
 
+       PR c++/57402
+       * init.c (build_vec_init): Use {} for arrays of class type.
+       (build_vec_delete): Don't take the address of the array.
+
        PR c++/57793
        * class.c (layout_class_type): Check for too-large class.
 
index 7acc7b582fecfa7be41deed3ef88a125e69fb1ea..808803d6524abc33add8f47f0219933e890d8ed2 100644 (file)
@@ -3561,10 +3561,14 @@ build_vec_init (tree base, tree maxindex, tree init,
            vec_free (new_vec);
        }
 
-      /* Clear out INIT so that we don't get confused below.  */
-      init = NULL_TREE;
       /* Any elements without explicit initializers get {}.  */
-      explicit_value_init_p = true;
+      if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
+       init = build_constructor (init_list_type_node, NULL);
+      else
+       {
+         init = NULL_TREE;
+         explicit_value_init_p = true;
+       }
     }
   else if (from_array)
     {
@@ -3636,11 +3640,11 @@ build_vec_init (tree base, tree maxindex, tree init,
        }
       else if (TREE_CODE (type) == ARRAY_TYPE)
        {
-         if (init != 0)
+         if (init && !BRACE_ENCLOSED_INITIALIZER_P (init))
            sorry
              ("cannot initialize multi-dimensional array with initializer");
          elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
-                                    0, 0,
+                                    0, init,
                                     explicit_value_init_p,
                                     0, complain);
        }
@@ -4121,7 +4125,7 @@ build_vec_delete (tree base, tree maxindex,
         bad name.  */
       maxindex = array_type_nelts_total (type);
       type = strip_array_types (type);
-      base = cp_build_addr_expr (base, complain);
+      base = decay_conversion (base, complain);
       if (base == error_mark_node)
        return error_mark_node;
       if (TREE_SIDE_EFFECTS (base))
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted45.C b/gcc/testsuite/g++.dg/cpp0x/defaulted45.C
new file mode 100644 (file)
index 0000000..e91b3a1
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do run }
+// { dg-require-effective-target c++11 }
+
+struct A
+{
+  int i;
+  A() = default;
+  A(int i): i{i} { }
+  ~A() {}
+};
+
+int main(int argc, char **argv)
+{
+  { int i[4] = { 42, 42, 42, 42 }; }
+  {
+    A a[4] = { argc };
+    if (a[1].i != 0)
+      __builtin_abort ();
+  }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/vla-initlist1.C b/gcc/testsuite/g++.dg/cpp1y/vla-initlist1.C
new file mode 100644 (file)
index 0000000..1e93835
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-do run }
+// { dg-options "-std=c++1y" }
+
+#include <initializer_list>
+
+struct A
+{
+  int i;
+  A(std::initializer_list<int>) { }
+  A(int i): i{i} { }
+  ~A() {}
+};
+
+int x = 4;
+int main(int argc, char **argv)
+{
+  { int i[x] = { 42, 42, 42, 42 }; }
+  {
+    A a[x] = { argc };
+    if (a[1].i != 42)
+      __builtin_abort ();
+  }
+}