diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/attrib32.C | 14 |
4 files changed, 32 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 12a826d..5e47e58 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2008-11-19 Jason Merrill <jason@redhat.com> + PR c++/36410 + * decl2.c (grokfield): Pass ATTR_FLAG_TYPE_IN_PLACE for a typedef + that names a class for linkage purposes. + PR c++/37563 * parser.c (cp_parser_pseudo_destructor_name): A pseudo-destructor name is not a declaration. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index b326752..a0ae6e4 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -803,7 +803,17 @@ grokfield (const cp_declarator *declarator, value = push_template_decl (value); if (attrlist) - cplus_decl_attributes (&value, attrlist, 0); + { + int attrflags = 0; + + /* If this is a typedef that names the class for linkage purposes + (7.1.3p8), apply any attributes directly to the type. */ + if (TAGGED_TYPE_P (TREE_TYPE (value)) + && value == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (value)))) + attrflags = ATTR_FLAG_TYPE_IN_PLACE; + + cplus_decl_attributes (&value, attrlist, attrflags); + } return value; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f1f6c28..305a992 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2008-11-19 Jason Merrill <jason@redhat.com> + PR c++/36410 + * g++.dg/ext/attrib32.C: Add member typedef case. + PR c++/37563 * g++.dg/template/pseudodtor5.C: New test. diff --git a/gcc/testsuite/g++.dg/ext/attrib32.C b/gcc/testsuite/g++.dg/ext/attrib32.C index 39363bb..77f71de 100644 --- a/gcc/testsuite/g++.dg/ext/attrib32.C +++ b/gcc/testsuite/g++.dg/ext/attrib32.C @@ -20,3 +20,17 @@ void bar2(U1 u1, U2 u2) foo2(u1); foo2(u2); } + +// PR c++/36410 +struct A +{ + typedef union + { + int i; + } B __attribute__((transparent_union)); +}; + +void foo(A::B b) +{ + b.i; +} |