https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88606
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|hubicka at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> --- When we reset TYPE_TRANSPARENT_AGGR because we cannot make it transparent we do so only on one variant, not all. The following fixes it: transparent-union-6.c:7:42: warning: union cannot be made transparent 7 | union __attribute__((transparent_union)) m30_u { | ^~~~~ transparent-union-6.c: In function ‘f’: transparent-union-6.c:16:23: error: incompatible type for argument 1 of ‘make_double’ 16 | return make_double (bar); | ^~~ | | | int transparent-union-6.c:11:21: note: expected ‘m30_t’ {aka ‘union m30_u’} but argument is of type ‘int’ 11 | double make_double (m30_t); | ^~~~~ Index: gcc/c/c-decl.c =================================================================== --- gcc/c/c-decl.c (revision 268530) +++ gcc/c/c-decl.c (working copy) @@ -8394,6 +8394,16 @@ finish_struct (location_t loc, tree t, t } } + /* If this was supposed to be a transparent union, but we can't + make it one, warn and turn off the flag. */ + if (TREE_CODE (t) == UNION_TYPE + && TYPE_TRANSPARENT_AGGR (t) + && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))) + { + TYPE_TRANSPARENT_AGGR (t) = 0; + warning_at (loc, 0, "union cannot be made transparent"); + } + /* Note: C_TYPE_INCOMPLETE_VARS overloads TYPE_VFIELD which is used in dwarf2out via rest_of_decl_compilation below and means something totally different. Since we will be clearing @@ -8406,22 +8416,13 @@ finish_struct (location_t loc, tree t, t { TYPE_FIELDS (x) = TYPE_FIELDS (t); TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t); + TYPE_TRANSPARENT_AGGR (x) = TYPE_TRANSPARENT_AGGR (t); C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t); C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t); C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t); C_TYPE_INCOMPLETE_VARS (x) = NULL_TREE; } - /* If this was supposed to be a transparent union, but we can't - make it one, warn and turn off the flag. */ - if (TREE_CODE (t) == UNION_TYPE - && TYPE_TRANSPARENT_AGGR (t) - && (!TYPE_FIELDS (t) || TYPE_MODE (t) != DECL_MODE (TYPE_FIELDS (t)))) - { - TYPE_TRANSPARENT_AGGR (t) = 0; - warning_at (loc, 0, "union cannot be made transparent"); - } - /* Update type location to the one of the definition, instead of e.g. a forward declaration. */ if (TYPE_STUB_DECL (t))