diff options
author | Jason Merrill <jason@redhat.com> | 2011-12-19 15:10:25 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-12-19 15:10:25 -0500 |
commit | d58d6eb5eca0451638d50752f3cbcc40084c4116 (patch) | |
tree | c2eb8f16afd3cc6631c120b09947312fc1972e08 /gcc | |
parent | 1784915af28cfbed713a9cd9a3ce4789c44ffb2b (diff) | |
download | gcc-d58d6eb5eca0451638d50752f3cbcc40084c4116.zip gcc-d58d6eb5eca0451638d50752f3cbcc40084c4116.tar.gz gcc-d58d6eb5eca0451638d50752f3cbcc40084c4116.tar.bz2 |
re PR c++/51228 (ICE with transparent union)
PR c++/51228
* c-common.c (handle_transparent_union_attribute): Check the first
field if the type is complete.
From-SVN: r182494
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c-family/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-family/c-common.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/transparent-union-1.c | 5 |
4 files changed, 35 insertions, 5 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 78854e2..2b8f325 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2011-12-19 Jason Merrill <jason@redhat.com> + + PR c++/51228 + * c-common.c (handle_transparent_union_attribute): Check the first + field if the type is complete. + 2011-12-15 Jonathan Wakely <jwakely.gcc@gmail.com> PR libstdc++/51365 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 3e50dcf..0562f26 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -6287,13 +6287,27 @@ handle_transparent_union_attribute (tree *node, tree name, if (TREE_CODE (type) == UNION_TYPE) { - /* When IN_PLACE is set, leave the check for FIELDS and MODE to - the code in finish_struct. */ + /* Make sure that the first field will work for a transparent union. + If the type isn't complete yet, leave the check to the code in + finish_struct. */ + if (TYPE_SIZE (type)) + { + tree first = first_field (type); + if (first == NULL_TREE + || DECL_ARTIFICIAL (first) + || TYPE_MODE (type) != DECL_MODE (first)) + goto ignored; + } + if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) { - if (TYPE_FIELDS (type) == NULL_TREE - || c_dialect_cxx () - || TYPE_MODE (type) != DECL_MODE (TYPE_FIELDS (type))) + /* If the type isn't complete yet, setting the flag + on a variant wouldn't ever be checked. */ + if (!TYPE_SIZE (type)) + goto ignored; + + /* build_duplicate_type doesn't work for C++. */ + if (c_dialect_cxx ()) goto ignored; /* A type variant isn't good enough, since we don't a cast diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f74bad7..70c3315 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-12-19 Jason Merrill <jason@redhat.com> + + PR c++/51228 + * c-c++-common/transparent-union-1.c: New. + 2011-12-19 Eric Botcazou <ebotcazou@adacore.com> PR tree-optimization/51580 diff --git a/gcc/testsuite/c-c++-common/transparent-union-1.c b/gcc/testsuite/c-c++-common/transparent-union-1.c new file mode 100644 index 0000000..3fb6e782 --- /dev/null +++ b/gcc/testsuite/c-c++-common/transparent-union-1.c @@ -0,0 +1,5 @@ +/* PR c++/51228 */ + +typedef union {} U __attribute__((transparent_union)); /* { dg-warning "ignored" } */ + +void foo(U u) {} |