Message ID | 50884604.2030308@oracle.com |
---|---|
State | New |
Headers | show |
On 10/24/2012 03:48 PM, Paolo Carlini wrote: > + error ("type transparent %q#T cannot be made transparent because " > + "a field has neither pointer nor integer type", t); I'd say "%q#T cannot be made transparent because %q#D has neither pointer nor integer type", t, field. OK with that change. Jason
Hi, On 10/24/2012 09:55 PM, Jason Merrill wrote: > On 10/24/2012 03:48 PM, Paolo Carlini wrote: >> + error ("type transparent %q#T cannot be made transparent >> because " >> + "a field has neither pointer nor integer type", t); > > I'd say "%q#T cannot be made transparent because %q#D has neither > pointer nor integer type", t, field. Unfortunately, I don't think we can name the specific field/member like this because it can be misleading in some cases (I had already tried ;) Consider: typedef union { int f; double x; } __attribute__(( __transparent_union__ )) example_t; we end up saying: ‘union<anonymous>’ cannot be made transparent because ‘int <anonymous union>::f’ has neither pointer nor integer type whereas the problem is actually x! Shall we content ourselves of something not naming the field? We are already doing better than the C front-end ;) Paolo.
.. Oh well, and the details of this are even subtler, because, assuming we want the exact same behavior of the C front-end, we are going to accept: typedef union { int* f; int y; } __attribute__(( __transparent_union__ )) example_t; and reject: typedef union { int f; int* y; } __attribute__(( __transparent_union__ )) example_t; thus we can't even talk about integer and pointer types generically... Essentially, what really matters is that the first field must be a pointer. Paolo.
On 10/24/2012 04:47 PM, Paolo Carlini wrote:
> Essentially, what really matters is that the first field must be a pointer.
In this case, yes. Let's just say what the issue is: the type of the
first field has a different ABI from the class overall.
Jason
Index: cp/class.c =================================================================== --- cp/class.c (revision 192762) +++ cp/class.c (working copy) @@ -6261,7 +6261,7 @@ 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); + error ("type transparent %q#T does not have any fields", t); TYPE_TRANSPARENT_AGGR (t) = 0; } else if (DECL_ARTIFICIAL (field)) @@ -6275,6 +6275,12 @@ finish_struct_1 (tree t) } TYPE_TRANSPARENT_AGGR (t) = 0; } + else if (TYPE_MODE (t) != DECL_MODE (field)) + { + error ("type transparent %q#T cannot be made transparent because " + "a field has neither pointer nor integer type", 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 "type transparent" } + double x; +} __attribute__(( __transparent_union__ )) example_t;