2005-10-11 Richard Henderson <rth@redhat.com>
+ PR c/24255
+ * c-typeck.c (convert_for_assignment): Use build_constructor_single
+ to initialize a transparent union instead of a nop_expr.
+
+2005-10-11 Richard Henderson <rth@redhat.com>
+
* Makefile.in (tree-ssa-dce.o): Depend on SCEV_H.
* tree-ssa-dce.c: Include tree-scalar-evolution.h.
(tree_ssa_dce_loop): Call scev_reset.
else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
&& (errtype == ic_argpass || errtype == ic_argpass_nonproto))
{
- tree memb_types;
- tree marginal_memb_type = 0;
+ tree memb, marginal_memb = NULL_TREE;
- for (memb_types = TYPE_FIELDS (type); memb_types;
- memb_types = TREE_CHAIN (memb_types))
+ for (memb = TYPE_FIELDS (type); memb ; memb = TREE_CHAIN (memb))
{
- tree memb_type = TREE_TYPE (memb_types);
+ tree memb_type = TREE_TYPE (memb);
if (comptypes (TYPE_MAIN_VARIANT (memb_type),
TYPE_MAIN_VARIANT (rhstype)))
break;
/* Keep looking for a better type, but remember this one. */
- if (!marginal_memb_type)
- marginal_memb_type = memb_type;
+ if (!marginal_memb)
+ marginal_memb = memb;
}
}
}
}
- if (memb_types || marginal_memb_type)
+ if (memb || marginal_memb)
{
- if (!memb_types)
+ if (!memb)
{
/* We have only a marginally acceptable member type;
it needs a warning. */
- tree ttl = TREE_TYPE (marginal_memb_type);
+ tree ttl = TREE_TYPE (TREE_TYPE (marginal_memb));
tree ttr = TREE_TYPE (rhstype);
/* Const and volatile mean something different for function
"from pointer target type"),
G_("return discards qualifiers from "
"pointer target type"));
+
+ memb = marginal_memb;
}
if (pedantic && (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl)))
pedwarn ("ISO C prohibits argument conversion to union type");
- return build1 (NOP_EXPR, type, rhs);
+ return build_constructor_single (type, memb, rhs);
}
}
--- /dev/null
+/* PR 24255 */
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+extern void abort (void);
+
+union wait { int w_status; };
+
+typedef union
+{
+ union wait *uptr;
+ int *iptr;
+} WAIT_STATUS __attribute__ ((__transparent_union__));
+
+int status;
+union wait wstatus;
+
+void __attribute__((noinline))
+test1 (WAIT_STATUS s)
+{
+ if (s.iptr != &status)
+ abort ();
+}
+
+void __attribute__((noinline))
+test2 (WAIT_STATUS s)
+{
+ if (s.uptr != &wstatus)
+ abort ();
+}
+
+int main()
+{
+ test1 (&status);
+ test2 (&wstatus);
+ return 0;
+}