diff options
author | Richard Henderson <rth@redhat.com> | 2005-10-12 16:34:09 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-10-12 16:34:09 -0700 |
commit | 52dd234b210c06bea54ef726995e1fce035329be (patch) | |
tree | e0ba09b20b9401b57ddfd7bb96ac65cafde86a0b /gcc/c-common.c | |
parent | 6deb03391308dcffb9bb4a4155cd27d7e60329f9 (diff) | |
download | gcc-52dd234b210c06bea54ef726995e1fce035329be.tar.gz |
re PR c/24255 (__transparent_union__ mishandled)
PR c/24255
* tree.h (DECL_TRANSPARENT_UNION): Remove.
* function.c (assign_parm_find_data_types): Don't support it.
* print-tree.c (print_node): Likewise.
* c-common.c (handle_transparent_union_attribute): Likewise.
Use build_duplicate_type.
* tree-inline.c (remap_type_1): Split out of remap_type;
properly remap aggregate fields.
(build_duplicate_type): New.
* doc/extend.texi (Variable Attributes): Remove documentation
for transparent_union.
From-SVN: r105338
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 4114fbf2b19..c5b409e77c0 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4309,39 +4309,43 @@ handle_transparent_union_attribute (tree *node, tree name, tree ARG_UNUSED (args), int flags, bool *no_add_attrs) { - tree decl = NULL_TREE; - tree *type = NULL; - int is_type = 0; + tree type = NULL; + + *no_add_attrs = true; if (DECL_P (*node)) { - decl = *node; - type = &TREE_TYPE (decl); - is_type = TREE_CODE (*node) == TYPE_DECL; + if (TREE_CODE (*node) != TYPE_DECL) + goto ignored; + node = &TREE_TYPE (*node); + type = *node; } else if (TYPE_P (*node)) - type = node, is_type = 1; + type = *node; + else + goto ignored; - if (is_type - && TREE_CODE (*type) == UNION_TYPE - && (decl == 0 - || (TYPE_FIELDS (*type) != 0 - && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type))))) + if (TREE_CODE (type) == UNION_TYPE) { + /* When IN_PLACE is set, leave the check for FIELDS and MODE to + the code in finish_struct. */ if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - *type = build_variant_type_copy (*type); - TYPE_TRANSPARENT_UNION (*type) = 1; - } - else if (decl != 0 && TREE_CODE (decl) == PARM_DECL - && TREE_CODE (*type) == UNION_TYPE - && TYPE_MODE (*type) == DECL_MODE (TYPE_FIELDS (*type))) - DECL_TRANSPARENT_UNION (decl) = 1; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; + { + if (TYPE_FIELDS (type) == NULL_TREE + || TYPE_MODE (type) != DECL_MODE (TYPE_FIELDS (type))) + goto ignored; + + /* A type variant isn't good enough, since we don't a cast + to such a type removed as a no-op. */ + *node = type = build_duplicate_type (type); + } + + TYPE_TRANSPARENT_UNION (type) = 1; + return NULL_TREE; } + ignored: + warning (OPT_Wattributes, "%qE attribute ignored", name); return NULL_TREE; } |