diff options
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/class.c | 6 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/anon2.C | 22 |
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; + }; +} |