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))

Reply via email to