aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/class.c6
-rw-r--r--gcc/cp/typeck2.c12
-rw-r--r--gcc/testsuite/g++.dg/other/anon2.C22
4 files changed, 43 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 06806fc..4c4cdce 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 305bde1..1fa9a12 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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))
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 5ba4611..fbedc13 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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
index 0000000..98d8c206
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/anon2.C
@@ -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;
+ };
+}