diff mbox

[C++] PR 53761

Message ID 50759082.3040403@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Oct. 10, 2012, 3:13 p.m. UTC
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  <paolo.carlini@oracle.com>

	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  <paolo.carlini@oracle.com>

	PR c++/53761
	* g++.dg/ext/transparent-union.C: New.

Comments

Jason Merrill Oct. 24, 2012, 4:57 p.m. UTC | #1
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.

> +	    error ("type transparent union %qT cannot be made transparent", t);

Let's say why not.

Jason
diff mbox

Patch

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;