re PR c++/38698 (ICE initializing union with initializer list)
authorJason Merrill <jason@redhat.com>
Sat, 3 Jan 2009 00:19:55 +0000 (19:19 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 3 Jan 2009 00:19:55 +0000 (19:19 -0500)
        PR c++/38698
        * typeck2.c (process_init_constructor_union): Handle excess
        initializers.
        (process_init_constructor_record): Likewise.

        PR c++/38684
        * typeck2.c (digest_init_r): Don't use process_init_constructor
        for non-aggregate classes.

From-SVN: r143024

gcc/cp/ChangeLog
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/initlist11.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist12.C [new file with mode: 0644]

index e6cb289..7ffa760 100644 (file)
@@ -1,3 +1,14 @@
+2009-01-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/38698
+       * typeck2.c (process_init_constructor_union): Handle excess
+       initializers.
+       (process_init_constructor_record): Likewise.
+
+       PR c++/38684
+       * typeck2.c (digest_init_r): Don't use process_init_constructor
+       for non-aggregate classes.
+
 2008-12-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/38647
index 207dd99..e313e4b 100644 (file)
@@ -820,7 +820,8 @@ digest_init_r (tree type, tree init, bool nested)
              || TREE_CODE (type) == UNION_TYPE
              || TREE_CODE (type) == COMPLEX_TYPE);
 
-  if (BRACE_ENCLOSED_INITIALIZER_P (init))
+  if (BRACE_ENCLOSED_INITIALIZER_P (init)
+      && !TYPE_NON_AGGREGATE_CLASS (type))
     return process_init_constructor (type, init);
   else
     {
@@ -1081,6 +1082,9 @@ process_init_constructor_record (tree type, tree init)
       CONSTRUCTOR_APPEND_ELT (v, field, next);
     }
 
+  if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)))
+    error ("too many initializers for %qT", type);
+    
   CONSTRUCTOR_ELTS (init) = v;
   return flags;
 }
@@ -1093,12 +1097,19 @@ static int
 process_init_constructor_union (tree type, tree init)
 {
   constructor_elt *ce;
+  int len;
 
   /* If the initializer was empty, use default zero initialization.  */
   if (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init)))
     return 0;
 
-  gcc_assert (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)) == 1);
+  len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init));
+  if (len > 1)
+    {
+      error ("too many initializers for %qT", type);
+      VEC_block_remove (constructor_elt, CONSTRUCTOR_ELTS (init), 1, len-1);
+    }
+
   ce = VEC_index (constructor_elt, CONSTRUCTOR_ELTS (init), 0);
 
   /* If this element specifies a field, initialize via that field.  */
index 9b59cb4..199784f 100644 (file)
@@ -1,3 +1,8 @@
+2009-01-02  Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/initlist11.C: New test.
+       * g++.dg/cpp0x/initlist12.C: New test.
+
 2009-01-02  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * gcc.dg/fixed-point/composite-type.c: Update wording of messages.
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist11.C b/gcc/testsuite/g++.dg/cpp0x/initlist11.C
new file mode 100644 (file)
index 0000000..789afc0
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/38684
+
+#include <initializer_list>
+
+struct Y {};
+
+struct X : Y { 
+  X(std::initializer_list<int>) {}
+}; 
+
+struct A { 
+  X v;
+};
+
+int main() {
+  A a{ {1,2,3} };
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist12.C b/gcc/testsuite/g++.dg/cpp0x/initlist12.C
new file mode 100644 (file)
index 0000000..f3329d9
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/38698
+
+struct A
+{
+  int i;
+};
+
+A a({1,2});
+
+union U
+{
+  int i,j;
+};
+
+U u({1,2});