typeck2.c (store_init_value): Don't re-digest a bracketed initializer.
authorJason Merrill <jason@redhat.com>
Thu, 11 Oct 2001 21:33:09 +0000 (17:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 11 Oct 2001 21:33:09 +0000 (17:33 -0400)
        * typeck2.c (store_init_value): Don't re-digest a bracketed
        initializer.

        * class.c (finish_struct_anon): Use TYPE_ANONYMOUS_P instead of
        ANON_AGGR_TYPE_P.

From-SVN: r46202

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/other/anon2.C [new file with mode: 0644]

index 06806fc40f237cc17ebd0ff2b64b0075a9db7f31..4c4cdce311aef185a8070eab5189bb35f9c72799 100644 (file)
@@ -1,3 +1,11 @@
+2001-10-11  Jason Merrill  <jason_merrill@redhat.com>
+
+       * typeck2.c (store_init_value): Don't re-digest a bracketed
+       initializer.
+
+       * class.c (finish_struct_anon): Use TYPE_ANONYMOUS_P instead of
+       ANON_AGGR_TYPE_P.
+
 2001-10-11  Richard Henderson  <rth@redhat.com>
 
        * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
index 305bde1d7fbde103d4630d2902779daf064301e2..1fa9a125dfbfa33c910759ea3ab012acce90e2c4 100644 (file)
@@ -2932,10 +2932,12 @@ finish_struct_anon (t)
                 declared, but we also find nested classes by noticing
                 the TYPE_DECL that we create implicitly.  You're
                 allowed to put one anonymous union inside another,
-                though, so we explicitly tolerate that.  */
+                though, so we explicitly tolerate that.  We use
+                TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that
+                we also allow unnamed types used for defining fields.  */
              if (DECL_ARTIFICIAL (elt) 
                  && (!DECL_IMPLICIT_TYPEDEF_P (elt)
-                     || ANON_AGGR_TYPE_P (TREE_TYPE (elt))))
+                     || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
                continue;
 
              if (DECL_NAME (elt) == constructor_name (t))
index 5ba46111cc06a4bf3bf0ebd16f3be800552f24be..fbedc13426a325f2a0171ec927d83996cf7b6d7b 100644 (file)
@@ -389,9 +389,15 @@ store_init_value (decl, init)
 
   /* End of special C++ code.  */
 
-  /* Digest the specified initializer into an expression.  */
-
-  value = digest_init (type, init, (tree *) 0);
+  /* We might have already run this bracketed initializer through
+     digest_init.  Don't do so again.  */
+  if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)
+      && TREE_TYPE (init)
+      && TYPE_MAIN_VARIANT (TREE_TYPE (init)) == TYPE_MAIN_VARIANT (type))
+    value = init;
+  else
+    /* Digest the specified initializer into an expression.  */
+    value = digest_init (type, init, (tree *) 0);
 
   /* Store the expression if valid; else report error.  */
 
diff --git a/gcc/testsuite/g++.dg/other/anon2.C b/gcc/testsuite/g++.dg/other/anon2.C
new file mode 100644 (file)
index 0000000..98d8c20
--- /dev/null
@@ -0,0 +1,22 @@
+// Test that we can have an unnamed struct inside an anonymous union.
+
+struct A
+{
+  union
+  {
+    struct { int i; } foo;
+  };
+};
+
+static union
+{
+  struct { int i; } foo;
+};
+
+int main ()
+{
+  union
+  {
+    struct { int i; } bar;
+  };
+}