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]

PATCH to build_type_qual_attribute_variant for debug/29436, debug/28334, etc.


build_type_qual_attribute_variant wanted to make a distinct copy of a type in order to attach attributes to it, but this causes problems for types that have members, i.e. RECORD/UNION/ENUMERAL_TYPE. The dwarf 2 backend assumes that there's only one type with a particular set of members, and crashes if we try to create multiple TYPE_MAIN_VARIANTs. Even if we fixed that, this sort of type copying doesn't work at all with the C++ type system, so it seems better to just ignore attributes applied after the definition of a tagged type.

Note that existing attributes packed, aligned, deprecated, unused and transparent_union are still allowed on typedefs of tagged type, but new usage should be avoided.

The tree-inline.c patch fixes build_duplicate_type, which has been a no-op since the GOMP merge. It's currently only used for the transparent_union attribute, but it seemed worth fixing as long as we have it around. Richard: you created the function in the first place, and also were the one to break it in the merge. I assume you don't object to this patch?

Tested on x86_64-pc-linux-gnu, applied to trunk.


2007-11-19  Jason Merrill  <jason@redhat.com>

	PR debug/28334, debug/29436 and many duplicates
	* tree.c (build_type_attribute_qual_variant): Refuse to make
	a distinct copy of a struct/enum type.  Use build_distinct_type_copy.
	* doc/extend.texi (Type Attributes): Don't encourage people to add
	attributes to struct/enum types in a typedef.  Fix
	transparent_union example.

	* tree-inline.c (remap_type_1): Remove code that's redundant with
	remap_type.
	(build_duplicate_type): Set id.copy_decl.
	* c-common.c (handle_transparent_union_attribute): Simplify logic.

Index: tree.c
===================================================================
*** tree.c	(revision 129844)
--- tree.c	(working copy)
*************** build_type_attribute_qual_variant (tree 
*** 3666,3680 ****
        tree ntype;
        enum tree_code code = TREE_CODE (ttype);
  
!       ntype = copy_node (ttype);
  
!       TYPE_POINTER_TO (ntype) = 0;
!       TYPE_REFERENCE_TO (ntype) = 0;
!       TYPE_ATTRIBUTES (ntype) = attribute;
  
!       /* Create a new main variant of TYPE.  */
!       TYPE_MAIN_VARIANT (ntype) = ntype;
!       TYPE_NEXT_VARIANT (ntype) = 0;
        set_type_quals (ntype, TYPE_UNQUALIFIED);
  
        hashcode = iterative_hash_object (code, hashcode);
--- 3666,3691 ----
        tree ntype;
        enum tree_code code = TREE_CODE (ttype);
  
!       /* Building a distinct copy of a tagged type is inappropriate; it
! 	 causes breakage in code that expects there to be a one-to-one
! 	 relationship between a struct and its fields.
! 	 build_duplicate_type is another solution (as used in
! 	 handle_transparent_union_attribute), but that doesn't play well
! 	 with the stronger C++ type identity model.  */
!       if (TREE_CODE (ttype) == RECORD_TYPE
! 	  || TREE_CODE (ttype) == UNION_TYPE
! 	  || TREE_CODE (ttype) == QUAL_UNION_TYPE
! 	  || TREE_CODE (ttype) == ENUMERAL_TYPE)
! 	{
! 	  warning (OPT_Wattributes,
! 		   "ignoring attributes applied to %qT after definition",
! 		   TYPE_MAIN_VARIANT (ttype));
! 	  return build_qualified_type (ttype, quals);
! 	}
  
!       ntype = build_distinct_type_copy (ttype);
  
!       TYPE_ATTRIBUTES (ntype) = attribute;
        set_type_quals (ntype, TYPE_UNQUALIFIED);
  
        hashcode = iterative_hash_object (code, hashcode);
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 129844)
--- tree-inline.c	(working copy)
*************** remap_decl (tree decl, copy_body_data *i
*** 273,296 ****
  static tree
  remap_type_1 (tree type, copy_body_data *id)
  {
-   tree *node;
    tree new, t;
  
-   if (type == NULL)
-     return type;
- 
-   /* See if we have remapped this type.  */
-   node = (tree *) pointer_map_contains (id->decl_map, type);
-   if (node)
-     return *node;
- 
-   /* The type only needs remapping if it's variably modified.  */
-   if (! variably_modified_type_p (type, id->src_fn))
-     {
-       insert_decl_map (id, type, type);
-       return type;
-     }
- 
    /* We do need a copy.  build and register it now.  If this is a pointer or
       reference type, remap the designated type and make a new pointer or
       reference type.  */
--- 273,280 ----
*************** build_duplicate_type (tree type)
*** 3575,3580 ****
--- 3559,3565 ----
    id.dst_fn = current_function_decl;
    id.src_cfun = cfun;
    id.decl_map = pointer_map_create ();
+   id.copy_decl = copy_decl_no_change;
  
    type = remap_type_1 (type, &id);
  
Index: c-common.c
===================================================================
*** c-common.c	(revision 129844)
--- c-common.c	(working copy)
*************** handle_transparent_union_attribute (tree
*** 5071,5091 ****
  				    tree ARG_UNUSED (args), int flags,
  				    bool *no_add_attrs)
  {
!   tree type = NULL;
  
    *no_add_attrs = true;
  
!   if (DECL_P (*node))
!     {
!       if (TREE_CODE (*node) != TYPE_DECL)
! 	goto ignored;
!       node = &TREE_TYPE (*node);
!       type = *node;
!     }
!   else if (TYPE_P (*node))
!     type = *node;
!   else
!     goto ignored;
  
    if (TREE_CODE (type) == UNION_TYPE)
      {
--- 5071,5083 ----
  				    tree ARG_UNUSED (args), int flags,
  				    bool *no_add_attrs)
  {
!   tree type;
  
    *no_add_attrs = true;
  
!   if (TREE_CODE (*node) == TYPE_DECL)
!     node = &TREE_TYPE (*node);
!   type = *node;
  
    if (TREE_CODE (type) == UNION_TYPE)
      {
Index: testsuite/gcc.c-torture/execute/mayalias-2.c
===================================================================
*** testsuite/gcc.c-torture/execute/mayalias-2.c	(revision 129844)
--- testsuite/gcc.c-torture/execute/mayalias-2.c	(working copy)
***************
*** 1,5 ****
! struct S { short x; };
! typedef struct S __attribute__((__may_alias__)) test;
  
  int f() {
    int a=10;
--- 1,4 ----
! typedef struct __attribute__((__may_alias__)) { short x; } test;
  
  int f() {
    int a=10;
Index: testsuite/gcc.c-torture/execute/mayalias-3.c
===================================================================
*** testsuite/gcc.c-torture/execute/mayalias-3.c	(revision 129844)
--- testsuite/gcc.c-torture/execute/mayalias-3.c	(working copy)
***************
*** 1,5 ****
! struct S { short x; };
! typedef struct S __attribute__((__may_alias__)) test;
  
  test *p;
  
--- 1,4 ----
! typedef struct __attribute__((__may_alias__)) { short x; } test;
  
  test *p;
  

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