aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2007-11-19 16:35:13 -0500
committerJason Merrill <jason@gcc.gnu.org>2007-11-19 16:35:13 -0500
commit4009f2e7f047aafc40fc9a27d884497e87ae0c05 (patch)
tree1d16dbdc75464cebb92ce8862847635b43953c3f /gcc
parent4d4447b56b603b0786a0de3601ba45618dc6816c (diff)
downloadgcc-4009f2e7f047aafc40fc9a27d884497e87ae0c05.zip
gcc-4009f2e7f047aafc40fc9a27d884497e87ae0c05.tar.gz
gcc-4009f2e7f047aafc40fc9a27d884497e87ae0c05.tar.bz2
PR debug/29436, c/32326
PR debug/29436, c/32326 * 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. From-SVN: r130297
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/c-common.c16
-rw-r--r--gcc/doc/extend.texi9
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/mayalias-2.c3
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/mayalias-3.c3
-rw-r--r--gcc/tree-inline.c17
-rw-r--r--gcc/tree.c25
7 files changed, 44 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 713450c..15bd247 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2007-11-19 Jason Merrill <jason@redhat.com>
+
+ PR debug/29436, c/32326
+ * 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.
+
2007-11-19 Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/rs6000.c (invalid_e500_subreg,
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 763745a..edc9b2c 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -5007,21 +5007,13 @@ handle_transparent_union_attribute (tree *node, tree name,
tree ARG_UNUSED (args), int flags,
bool *no_add_attrs)
{
- tree type = NULL;
+ tree type;
*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 (*node) == TYPE_DECL)
+ node = &TREE_TYPE (*node);
+ type = *node;
if (TREE_CODE (type) == UNION_TYPE)
{
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 1c0d476..c86052e 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -3938,8 +3938,9 @@ attributes in header files without being concerned about a possible
macro of the same name. For example, you may use @code{__aligned__}
instead of @code{aligned}.
-You may specify type attributes either in a @code{typedef} declaration
-or in an enum, struct or union type declaration or definition.
+You may specify type attributes in an enum, struct or union type
+declaration or definition, or for other types in a @code{typedef}
+declaration.
For an enum, struct or union type, you may specify attributes either
between the enum, struct or union tag and the name of the type, or
@@ -4098,11 +4099,11 @@ less useful. Instead, @code{<sys/wait.h>} might define the interface
as follows:
@smallexample
-typedef union
+typedef union __attribute__ ((__transparent_union__))
@{
int *__ip;
union wait *__up;
- @} wait_status_ptr_t __attribute__ ((__transparent_union__));
+ @} wait_status_ptr_t;
pid_t wait (wait_status_ptr_t);
@end smallexample
diff --git a/gcc/testsuite/gcc.c-torture/execute/mayalias-2.c b/gcc/testsuite/gcc.c-torture/execute/mayalias-2.c
index 5a1a9d5..39c010d 100644
--- a/gcc/testsuite/gcc.c-torture/execute/mayalias-2.c
+++ b/gcc/testsuite/gcc.c-torture/execute/mayalias-2.c
@@ -1,5 +1,4 @@
-struct S { short x; };
-typedef struct S __attribute__((__may_alias__)) test;
+typedef struct __attribute__((__may_alias__)) { short x; } test;
int f() {
int a=10;
diff --git a/gcc/testsuite/gcc.c-torture/execute/mayalias-3.c b/gcc/testsuite/gcc.c-torture/execute/mayalias-3.c
index 3d66791..53bd07a 100644
--- a/gcc/testsuite/gcc.c-torture/execute/mayalias-3.c
+++ b/gcc/testsuite/gcc.c-torture/execute/mayalias-3.c
@@ -1,5 +1,4 @@
-struct S { short x; };
-typedef struct S __attribute__((__may_alias__)) test;
+typedef struct __attribute__((__may_alias__)) { short x; } test;
test *p;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index e0d4093..da52d6c 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -273,24 +273,8 @@ remap_decl (tree decl, copy_body_data *id)
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. */
@@ -3593,6 +3577,7 @@ build_duplicate_type (tree type)
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);
diff --git a/gcc/tree.c b/gcc/tree.c
index 81c54d0..9c65474 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3666,15 +3666,26 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
tree ntype;
enum tree_code code = TREE_CODE (ttype);
- ntype = copy_node (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);
+ }
- TYPE_POINTER_TO (ntype) = 0;
- TYPE_REFERENCE_TO (ntype) = 0;
- TYPE_ATTRIBUTES (ntype) = attribute;
+ ntype = build_distinct_type_copy (ttype);
- /* Create a new main variant of TYPE. */
- TYPE_MAIN_VARIANT (ntype) = ntype;
- TYPE_NEXT_VARIANT (ntype) = 0;
+ TYPE_ATTRIBUTES (ntype) = attribute;
set_type_quals (ntype, TYPE_UNQUALIFIED);
hashcode = iterative_hash_object (code, hashcode);