OSDN Git Service

* typeck2.c (store_init_value): Don't re-digest a bracketed
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Oct 2001 21:33:09 +0000 (21:33 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 11 Oct 2001 21:33:09 +0000 (21:33 +0000)
        initializer.

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46202 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 06806fc..4c4cdce 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 305bde1..1fa9a12 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 5ba4611..fbedc13 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;
+  };
+}