Patchwork [C++] PR 53761

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 24, 2012, 7:48 p.m.
Message ID <50884604.2030308@oracle.com>
Download mbox | patch
Permalink /patch/193940/
State New
Headers show

Comments

Paolo Carlini - Oct. 24, 2012, 7:48 p.m.
Hi,

On 10/24/2012 06:57 PM, Jason Merrill wrote:
> On 10/10/2012 11:13 AM, Paolo Carlini wrote:
>> -      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);
> If you use %q#T you don't need to repeat the class-key.
Indeed.
>
>> +        error ("type transparent union %qT cannot be made 
>> transparent", t);
>
> Let's say why not.
Thus I tested the below.

Thanks,
Paolo.

//////////////////////
Jason Merrill - Oct. 24, 2012, 7:55 p.m.
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
Paolo Carlini - Oct. 24, 2012, 8:19 p.m.
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.
Paolo Carlini - Oct. 24, 2012, 8:47 p.m.
.. 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.
Jason Merrill - Oct. 25, 2012, 2:07 p.m.
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

Patch

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;