This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++] PATCH for 13170 to class attribute handling


PR 13170 is caused by the parser temporarily storing attributes specified
in the class head in TYPE_ATTRIBUTES, and then removing them later if they
don't apply.  As a result, we were winding up with variants both with and
without the attribute, causing confusion and death.

This patch changes the parser to store the class head attributes in a local
variable in cp_parser_class_specifier rather than in the type itself.  As a
side-effect, we can remove the attribute handling from xref_tag, where it
really doesn't belong.

Tested x86_64-pc-linux-gnu, applied to trunk and 3.4.  Test in
g++.dg/ext/attrib14.C.

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.

*** cp-tree.h.~1~	2004-02-24 13:30:54.000000000 -0500
--- cp-tree.h	2004-03-08 15:50:35.000000000 -0500
*************** extern tree get_scope_of_declarator     
*** 3647,3653 ****
  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_from_type			(tree, tree, int);
  extern void xref_basetypes			(tree, tree);
  extern tree start_enum				(tree);
--- 3647,3653 ----
  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, bool, bool);
  extern tree xref_tag_from_type			(tree, tree, int);
  extern void xref_basetypes			(tree, tree);
  extern tree start_enum				(tree);
*** decl.c.~1~	2004-03-05 17:37:41.000000000 -0500
--- decl.c	2004-03-08 15:50:38.000000000 -0500
*************** check_elaborated_type_specifier (enum ta
*** 9303,9310 ****
     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.
  
     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
--- 9303,9309 ----
     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.
  
     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
*************** check_elaborated_type_specifier (enum ta
*** 9314,9320 ****
     a set of template parameters.  */
  
  tree
! xref_tag (enum tag_types tag_code, tree name, tree attributes, 
  	  bool globalize, bool template_header_p)
  {
    enum tree_code code;
--- 9313,9319 ----
     a set of template parameters.  */
  
  tree
! xref_tag (enum tag_types tag_code, tree name,
  	  bool globalize, bool template_header_p)
  {
    enum tree_code code;
*************** xref_tag (enum tag_types tag_code, tree 
*** 9470,9485 ****
  	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);
  }
  
--- 9469,9474 ----
*************** xref_tag_from_type (tree old, tree id, i
*** 9496,9502 ****
    if (id == NULL_TREE)
      id = TYPE_IDENTIFIER (old);
  
!   return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize, false);
  }
  
  /* REF is a type (named NAME), for which we have just seen some
--- 9485,9491 ----
    if (id == NULL_TREE)
      id = TYPE_IDENTIFIER (old);
  
!   return xref_tag (tag_kind, id, globalize, false);
  }
  
  /* REF is a type (named NAME), for which we have just seen some
*** parser.c.~1~	2004-03-05 17:37:42.000000000 -0500
--- parser.c	2004-03-08 15:51:30.000000000 -0500
*************** static tree cp_parser_class_name
*** 1523,1529 ****
  static tree cp_parser_class_specifier
    (cp_parser *);
  static tree cp_parser_class_head
!   (cp_parser *, bool *);
  static enum tag_types cp_parser_class_key
    (cp_parser *);
  static void cp_parser_member_specification_opt
--- 1523,1529 ----
  static tree cp_parser_class_specifier
    (cp_parser *);
  static tree cp_parser_class_head
!   (cp_parser *, bool *, tree *);
  static enum tag_types cp_parser_class_key
    (cp_parser *);
  static void cp_parser_member_specification_opt
*************** cp_parser_elaborated_type_specifier (cp_
*** 9293,9299 ****
  	    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,
--- 9293,9298 ----
*************** cp_parser_class_specifier (cp_parser* pa
*** 11786,11792 ****
  {
    cp_token *token;
    tree type;
!   tree attributes = NULL_TREE;
    int has_trailing_semicolon;
    bool nested_name_specifier_p;
    unsigned saved_num_template_parameter_lists;
--- 11785,11791 ----
  {
    cp_token *token;
    tree type;
!   tree attributes;
    int has_trailing_semicolon;
    bool nested_name_specifier_p;
    unsigned saved_num_template_parameter_lists;
*************** cp_parser_class_specifier (cp_parser* pa
*** 11796,11802 ****
  
    /* Parse the class-head.  */
    type = cp_parser_class_head (parser,
! 			       &nested_name_specifier_p);
    /* If the class-head was a semantic disaster, skip the entire body
       of the class.  */
    if (!type)
--- 11795,11802 ----
  
    /* Parse the class-head.  */
    type = cp_parser_class_head (parser,
! 			       &nested_name_specifier_p,
! 			       &attributes);
    /* If the class-head was a semantic disaster, skip the entire body
       of the class.  */
    if (!type)
*************** cp_parser_class_specifier (cp_parser* pa
*** 11839,11855 ****
       missing trailing `;'.  */
    token = cp_lexer_peek_token (parser->lexer);
    has_trailing_semicolon = (token->type == CPP_SEMICOLON);
!   /* Look for 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);
      }
    if (pop_p)
      pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
    /* If this class is not itself within the scope of another class,
--- 11839,11852 ----
       missing trailing `;'.  */
    token = cp_lexer_peek_token (parser->lexer);
    has_trailing_semicolon = (token->type == CPP_SEMICOLON);
!   /* Look for trailing attributes to apply to this class.  */
    if (cp_parser_allow_gnu_extensions_p (parser))
      {
!       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,
*************** cp_parser_class_specifier (cp_parser* pa
*** 11956,11962 ****
  
  static tree
  cp_parser_class_head (cp_parser* parser,
! 		      bool* nested_name_specifier_p)
  {
    cp_token *token;
    tree nested_name_specifier;
--- 11953,11960 ----
  
  static tree
  cp_parser_class_head (cp_parser* parser,
! 		      bool* nested_name_specifier_p,
! 		      tree *attributes_p)
  {
    cp_token *token;
    tree nested_name_specifier;
*************** cp_parser_class_head (cp_parser* parser,
*** 12183,12189 ****
        /* If the class was unnamed, create a dummy name.  */
        if (!id)
  	id = make_anon_name ();
!       type = xref_tag (class_key, id, attributes, /*globalize=*/false,
  		       parser->num_template_parameter_lists);
      }
    else
--- 12181,12187 ----
        /* If the class was unnamed, create a dummy name.  */
        if (!id)
  	id = make_anon_name ();
!       type = xref_tag (class_key, id, /*globalize=*/false,
  		       parser->num_template_parameter_lists);
      }
    else
*************** cp_parser_class_head (cp_parser* parser,
*** 12267,12272 ****
--- 12265,12271 ----
        end_specialization ();
        --parser->num_template_parameter_lists;
      }
+   *attributes_p = attributes;
    return type;
  }
  
*** rtti.c.~1~	2004-02-10 18:59:02.000000000 -0500
--- rtti.c	2004-03-08 15:50:36.000000000 -0500
*************** init_rtti_processing (void)
*** 120,126 ****
    push_namespace (std_identifier);
    type_info_type_node 
      = xref_tag (class_type, get_identifier ("type_info"),
! 		/*attributes=*/NULL_TREE, true, false);
    pop_namespace ();
    const_type_info_type = build_qualified_type (type_info_type_node, 
  					       TYPE_QUAL_CONST);
--- 120,126 ----
    push_namespace (std_identifier);
    type_info_type_node 
      = xref_tag (class_type, get_identifier ("type_info"),
! 		true, false);
    pop_namespace ();
    const_type_info_type = build_qualified_type (type_info_type_node, 
  					       TYPE_QUAL_CONST);
*************** build_dynamic_cast_1 (tree type, tree ex
*** 635,641 ****
  	      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
--- 635,640 ----
*************** tinfo_base_init (tree desc, tree target)
*** 777,783 ****
    
        push_nested_namespace (abi_node);
        real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
! 			    /*attributes=*/NULL_TREE, true, false);
        pop_nested_namespace (abi_node);
    
        if (!COMPLETE_TYPE_P (real_type))
--- 776,782 ----
    
        push_nested_namespace (abi_node);
        real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
! 			    true, false);
        pop_nested_namespace (abi_node);
    
        if (!COMPLETE_TYPE_P (real_type))
*************** emit_support_tinfos (void)
*** 1373,1379 ****
    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))
--- 1372,1377 ----

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]