From patchwork Wed Oct 10 15:13:06 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C++] PR 53761 Date: Wed, 10 Oct 2012 05:13:06 -0000 From: Paolo Carlini X-Patchwork-Id: 190688 Message-Id: <50759082.3040403@oracle.com> To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill Hi, in this PR, at variance with the C front-end, we don't check well enough the aggregate type - in finish_struct_1 - and we ICE later. Then I'm essentially copying from the C front-end the check. Some details: 1- In these checks, eg, no fields too, the C front-end only warns, zeroes TYPE_TRANSPARENT_AGGR and continues. We emit an hard error and zero TYPE_TRANSPARENT_AGGR as error recovery measure. I'm doing the same for this additional check. 2- The existing diagnostics, eg, for no fields, again, talks about "class", I think we can distinguish "class" vs "union" (when it makes sense, I'm leaving alone bases, virtuals, already rejected by the parser for unions) Tested x86_64-linux, as usual. Thanks, Paolo. ////////////////////////// /cp 2012-10-10 Paolo Carlini PR c++/53761 * class.c (finish_struct_1): Reject aggregates decorated with __transparent_union__ which cannot be made transparent. /testsuite 2012-10-10 Paolo Carlini PR c++/53761 * g++.dg/ext/transparent-union.C: New. Index: cp/class.c =================================================================== --- cp/class.c (revision 192309) +++ cp/class.c (working copy) @@ -6181,7 +6181,10 @@ finish_struct_1 (tree t) tree field = first_field (t); if (field == NULL_TREE || error_operand_p (field)) { - error ("type transparent class %qT does not have any fields", t); + if (TREE_CODE (t) == UNION_TYPE) + error ("type transparent union %qT does not have any fields", t); + else + error ("type transparent class %qT does not have any fields", t); TYPE_TRANSPARENT_AGGR (t) = 0; } else if (DECL_ARTIFICIAL (field)) @@ -6195,6 +6198,14 @@ finish_struct_1 (tree t) } TYPE_TRANSPARENT_AGGR (t) = 0; } + else if (TYPE_MODE (t) != DECL_MODE (field)) + { + if (TREE_CODE (t) == UNION_TYPE) + error ("type transparent union %qT cannot be made transparent", t); + else + error ("type transparent class %qT cannot be made transparent", t); + TYPE_TRANSPARENT_AGGR (t) = 0; + } } } Index: testsuite/g++.dg/ext/transparent-union.C =================================================================== --- testsuite/g++.dg/ext/transparent-union.C (revision 0) +++ testsuite/g++.dg/ext/transparent-union.C (working copy) @@ -0,0 +1,5 @@ +// PR c++/53761 + +typedef union { // { dg-error "transparent union" } + double x; +} __attribute__(( __transparent_union__ )) example_t;