From 0f7adc039f06a38744b8d5e2817d96d6f3825b0a Mon Sep 17 00:00:00 2001 From: rth Date: Tue, 11 Oct 2005 22:52:04 +0000 Subject: [PATCH] PR c/24255 * c-typeck.c (convert_for_assignment): Use build_constructor_single to initialize a transparent union instead of a nop_expr. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@105270 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 +++++ gcc/c-typeck.c | 22 +++++++++--------- gcc/testsuite/gcc.dg/transparent-union-5.c | 37 ++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/transparent-union-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 88834b6..9d7fc4e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2005-10-11 Richard Henderson + 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 + * 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. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 8a90476..cf9798a 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -3799,13 +3799,11 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, 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))) @@ -3837,8 +3835,8 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, 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; } } @@ -3852,13 +3850,13 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, } } - 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 @@ -3893,12 +3891,14 @@ convert_for_assignment (tree type, tree rhs, enum impl_conv errtype, "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); } } diff --git a/gcc/testsuite/gcc.dg/transparent-union-5.c b/gcc/testsuite/gcc.dg/transparent-union-5.c new file mode 100644 index 0000000..47e245e --- /dev/null +++ b/gcc/testsuite/gcc.dg/transparent-union-5.c @@ -0,0 +1,37 @@ +/* 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; +} -- 2.7.4