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.carl...@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.carl...@oracle.com>
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;