PR c++/13170
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Mar 2004 22:24:45 +0000 (22:24 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Mar 2004 22:24:45 +0000 (22:24 +0000)
        * decl.c (xref_tag): Remove attribute handling.
        * cp-tree.h: Adjust prototype.
        * decl.c, parser.c, rtti.c: Adjust callers.
        * parser.c (cp_parser_class_head): Pass back attributes in the
        class head.
        (cp_parser_class_specifier): Adjust.

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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/parser.c
gcc/cp/rtti.c
gcc/testsuite/g++.dg/ext/attrib14.C [new file with mode: 0644]

index 70f15ff..c64bb21 100644 (file)
@@ -1,3 +1,13 @@
+2004-03-08  Jason Merrill  <jason@redhat.com>
+
+       PR c++/13170
+       * decl.c (xref_tag): Remove attribute handling.
+       * cp-tree.h: Adjust prototype.
+       * decl.c, parser.c, rtti.c: Adjust callers.
+       * parser.c (cp_parser_class_head): Pass back attributes in the
+       class head.
+       (cp_parser_class_specifier): Adjust.
+
 2004-03-08  Matt Austern  <austern@apple.com>
 
        PR debug/14079
index 36acc5a..55b077e 100644 (file)
@@ -3647,7 +3647,7 @@ extern tree get_scope_of_declarator             (tree);
 extern void grok_special_member_properties     (tree);
 extern int grok_ctor_properties                        (tree, tree);
 extern bool grok_op_properties                 (tree, int, bool);
-extern tree xref_tag                           (enum tag_types, tree, tree, bool, bool);
+extern tree xref_tag                           (enum tag_types, tree, bool, bool);
 extern tree xref_tag_from_type                 (tree, tree, int);
 extern void xref_basetypes                     (tree, tree);
 extern tree start_enum                         (tree);
index 1c0ed25..8c2405f 100644 (file)
@@ -9303,8 +9303,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
    Define the tag as a forward-reference if it is not defined.
 
    If a declaration is given, process it here, and report an error if
-   multiple declarations are not identical.  ATTRIBUTE is the attribute
-   appeared in this declaration.
+   multiple declarations are not identical.
 
    GLOBALIZE is false when this is also a definition.  Only look in
    the current frame for the name (since C++ allows new names in any
@@ -9314,7 +9313,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
    a set of template parameters.  */
 
 tree
-xref_tag (enum tag_types tag_code, tree name, tree attributes, 
+xref_tag (enum tag_types tag_code, tree name,
          bool globalize, bool template_header_p)
 {
   enum tree_code code;
@@ -9470,16 +9469,6 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
        redeclare_class_template (t, current_template_parms);
     }
 
-  /* Add attributes only when defining a class. */
-  if (attributes)
-    {
-      /* The only place that xref_tag is called with non-null
-        attributes is in cp_parser_class_head(), when defining a
-        class.  */ 
-      my_friendly_assert (TYPE_ATTRIBUTES (t) == NULL_TREE, 20040113);
-      TYPE_ATTRIBUTES (t) = attributes;
-    }
-
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
 
@@ -9496,7 +9485,7 @@ xref_tag_from_type (tree old, tree id, int globalize)
   if (id == NULL_TREE)
     id = TYPE_IDENTIFIER (old);
 
-  return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false);
+  return xref_tag (tag_kind, id, globalize, false);
 }
 
 /* REF is a type (named NAME), for which we have just seen some
index 9184f0e..b633653 100644 (file)
@@ -1523,7 +1523,7 @@ static tree cp_parser_class_name
 static tree cp_parser_class_specifier
   (cp_parser *);
 static tree cp_parser_class_head
-  (cp_parser *, bool *);
+  (cp_parser *, bool *, tree *);
 static enum tag_types cp_parser_class_key
   (cp_parser *);
 static void cp_parser_member_specification_opt
@@ -9293,7 +9293,6 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
            warning ("type attributes are honored only at type definition");
 
          type = xref_tag (tag_type, identifier,
-                          /*attributes=*/NULL_TREE,
                           (is_friend
                            || !is_declaration
                            || cp_lexer_next_token_is_not (parser->lexer,
@@ -11786,7 +11785,7 @@ cp_parser_class_specifier (cp_parser* parser)
 {
   cp_token *token;
   tree type;
-  tree attributes = NULL_TREE;
+  tree attributes;
   int has_trailing_semicolon;
   bool nested_name_specifier_p;
   unsigned saved_num_template_parameter_lists;
@@ -11796,7 +11795,8 @@ cp_parser_class_specifier (cp_parser* parser)
 
   /* Parse the class-head.  */
   type = cp_parser_class_head (parser,
-                              &nested_name_specifier_p);
+                              &nested_name_specifier_p,
+                              &attributes);
   /* If the class-head was a semantic disaster, skip the entire body
      of the class.  */
   if (!type)
@@ -11839,17 +11839,14 @@ cp_parser_class_specifier (cp_parser* parser)
      missing trailing `;'.  */
   token = cp_lexer_peek_token (parser->lexer);
   has_trailing_semicolon = (token->type == CPP_SEMICOLON);
-  /* Look for attributes to apply to this class.  */
+  /* Look for trailing attributes to apply to this class.  */
   if (cp_parser_allow_gnu_extensions_p (parser))
-    attributes = cp_parser_attributes_opt (parser);
-  /* If we got any attributes in class_head, xref_tag will stick them in
-     TREE_TYPE of the type.  Grab them now.  */
-  if (type != error_mark_node)
     {
-      attributes = chainon (TYPE_ATTRIBUTES (type), attributes);
-      TYPE_ATTRIBUTES (type) = NULL_TREE;
-      type = finish_struct (type, attributes);
+      tree sub_attr = cp_parser_attributes_opt (parser);
+      attributes = chainon (attributes, sub_attr);
     }
+  if (type != error_mark_node)
+    type = finish_struct (type, attributes);
   if (pop_p)
     pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
   /* If this class is not itself within the scope of another class,
@@ -11956,7 +11953,8 @@ cp_parser_class_specifier (cp_parser* parser)
 
 static tree
 cp_parser_class_head (cp_parser* parser,
-                     bool* nested_name_specifier_p)
+                     bool* nested_name_specifier_p,
+                     tree *attributes_p)
 {
   cp_token *token;
   tree nested_name_specifier;
@@ -12183,7 +12181,7 @@ cp_parser_class_head (cp_parser* parser,
       /* If the class was unnamed, create a dummy name.  */
       if (!id)
        id = make_anon_name ();
-      type = xref_tag (class_key, id, attributes, /*globalize=*/false,
+      type = xref_tag (class_key, id, /*globalize=*/false,
                       parser->num_template_parameter_lists);
     }
   else
@@ -12267,6 +12265,7 @@ cp_parser_class_head (cp_parser* parser,
       end_specialization ();
       --parser->num_template_parameter_lists;
     }
+  *attributes_p = attributes;
   return type;
 }
 
index fb611a7..e9c0616 100644 (file)
@@ -120,7 +120,7 @@ init_rtti_processing (void)
   push_namespace (std_identifier);
   type_info_type_node 
     = xref_tag (class_type, get_identifier ("type_info"),
-               /*attributes=*/NULL_TREE, true, false);
+               true, false);
   pop_namespace ();
   const_type_info_type = build_qualified_type (type_info_type_node, 
                                               TYPE_QUAL_CONST);
@@ -635,7 +635,6 @@ build_dynamic_cast_1 (tree type, tree expr)
              push_nested_namespace (ns);
              tinfo_ptr = xref_tag (class_type,
                                    get_identifier ("__class_type_info"),
-                                   /*attributes=*/NULL_TREE,
                                    true, false);
              
              tinfo_ptr = build_pointer_type
@@ -777,7 +776,7 @@ tinfo_base_init (tree desc, tree target)
   
       push_nested_namespace (abi_node);
       real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
-                           /*attributes=*/NULL_TREE, true, false);
+                           true, false);
       pop_nested_namespace (abi_node);
   
       if (!COMPLETE_TYPE_P (real_type))
@@ -1373,7 +1372,6 @@ emit_support_tinfos (void)
   push_nested_namespace (abi_node);
   bltn_type = xref_tag (class_type,
                        get_identifier ("__fundamental_type_info"), 
-                       /*attributes=*/NULL_TREE,
                        true, false);
   pop_nested_namespace (abi_node);
   if (!COMPLETE_TYPE_P (bltn_type))
diff --git a/gcc/testsuite/g++.dg/ext/attrib14.C b/gcc/testsuite/g++.dg/ext/attrib14.C
new file mode 100644 (file)
index 0000000..1b22729
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/13170
+// The bogus attribute is ignored, but was in TYPE_ATTRIBUTES during parsing of the class,
+// causing some variants to have it and some not.
+
+struct __attribute__((bogus)) A
+{
+    virtual ~A();
+    void foo(const A&);
+    void bar(const A&);
+};                             // { dg-warning "ignored" "" }
+
+void A::foo(const A&)   {}
+void A::bar(const A& a) { foo(a); }