re PR c++/35315 (ICE with attribute transparent_union)
authorJason Merrill <jason@redhat.com>
Tue, 26 Feb 2008 18:09:02 +0000 (13:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 26 Feb 2008 18:09:02 +0000 (13:09 -0500)
        PR c++/35315
        * attribs.c (decl_attributes): Leave ATTR_FLAG_TYPE_IN_PLACE
        alone if it's the naming decl for the type's main variant.
        * cp/decl.c (grokdeclarator): Allow a typedef of an unnamed struct
        to name the struct for linkage purposes even if it has attributes.
        (start_decl): In that case, set ATTR_FLAG_TYPE_IN_PLACE.

From-SVN: r132681

gcc/ChangeLog
gcc/attribs.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/g++.dg/ext/attrib32.C [new file with mode: 0644]

index 35ee86e328b02033b23d10df5e4c44272fa98616..02f55c96335bfc1174321190796d63d9bf204510 100644 (file)
@@ -1,3 +1,9 @@
+2008-02-26  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35315
+       * attribs.c (decl_attributes): Leave ATTR_FLAG_TYPE_IN_PLACE 
+       alone if it's the naming decl for the type's main variant.
+
 2008-02-26  Tom Tromey  <tromey@redhat.com>
 
        * system.h (USE_MAPPED_LOCATION): Poison.
index 31b92cad508bff2c875fa3b9e7e6c2a7aec5d49f..767035b5dd10af44b63f7d19e86714170635d1ba 100644 (file)
@@ -280,7 +280,11 @@ decl_attributes (tree *node, tree attributes, int flags)
       if (spec->type_required && DECL_P (*anode))
        {
          anode = &TREE_TYPE (*anode);
-         flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
+         /* Allow ATTR_FLAG_TYPE_IN_PLACE for the type's naming decl.  */
+         if (!(TREE_CODE (*anode) == TYPE_DECL
+               && *anode == TYPE_NAME (TYPE_MAIN_VARIANT
+                                       (TREE_TYPE (*anode)))))
+           flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
        }
 
       if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE
index f56c61c7310beef5e292192a4b134560b7f4c762..2a06b6f9adca1817ef716ac63df073f1ae17ce56 100644 (file)
@@ -1,3 +1,10 @@
+2008-02-26  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35315
+       * decl.c (grokdeclarator): Allow a typedef of an unnamed struct
+       to name the struct for linkage purposes even if it has attributes.
+       (start_decl): In that case, set ATTR_FLAG_TYPE_IN_PLACE.
+
 2008-02-26  Tom Tromey  <tromey@redhat.com>
 
        * parser.c (eof_token): Remove old location code.
 2008-02-12  Jason Merrill  <jason@redhat.com>
 
        PR c++/34824
-       * call.c (convert_like_real): Pass LOOKUP_ONLYCONVERTING to build_temp
+       * call.c (convert_like_real): Pass LOOKUP_NO_CONVERSION to build_temp
        if we're doing conversions to call a user-defined conversion function.
 
 2008-02-12  Steven Bosscher  <steven@gcc.gnu.org>
index 5a5a81a4d01e0ab7cb0110b5bcc1cd00b5e3fae0..52a600440f9ddd8b291b59ed4ae428e19ffec4d8 100644 (file)
@@ -3957,6 +3957,7 @@ start_decl (const cp_declarator *declarator,
   tree type;
   tree context;
   bool was_public;
+  int flags;
 
   *pushed_scope_p = NULL_TREE;
 
@@ -4018,8 +4019,17 @@ start_decl (const cp_declarator *declarator,
        TREE_STATIC (decl) = 1;
     }
 
+  /* If this is a typedef that names the class for linkage purposes
+     (7.1.3p8), apply any attributes directly to the type.  */
+  if (TREE_CODE (decl) == TYPE_DECL
+      && TAGGED_TYPE_P (TREE_TYPE (decl))
+      && decl == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))))
+    flags = ATTR_FLAG_TYPE_IN_PLACE;
+  else
+    flags = 0;
+
   /* Set attributes here so if duplicate decl, will have proper attributes.  */
-  cplus_decl_attributes (&decl, attributes, 0);
+  cplus_decl_attributes (&decl, attributes, flags);
 
   /* Dllimported symbols cannot be defined.  Static data members (which
      can be initialized in-class and dllimported) go through grokfield,
@@ -8556,8 +8566,6 @@ grokdeclarator (const cp_declarator *declarator,
          && TYPE_NAME (type)
          && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
          && TYPE_ANONYMOUS_P (type)
-         /* Don't do this if there are attributes.  */
-         && (!attrlist || !*attrlist)
          && cp_type_quals (type) == TYPE_UNQUALIFIED)
        {
          tree oldname = TYPE_NAME (type);
diff --git a/gcc/testsuite/g++.dg/ext/attrib32.C b/gcc/testsuite/g++.dg/ext/attrib32.C
new file mode 100644 (file)
index 0000000..523015c
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/35315
+
+typedef union { int i; } U __attribute__((transparent_union));
+
+static void foo(U) {}
+static void foo(int) {}
+
+void bar()
+{
+  foo(0);
+}