Bug 24255 - [4.1 regression] __transparent_union__ mishandled
Summary: [4.1 regression] __transparent_union__ mishandled
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.1.0
Assignee: Richard Henderson
URL:
Keywords: ABI, wrong-code
Depends on:
Blocks:
 
Reported: 2005-10-07 11:37 UTC by Andreas Schwab
Modified: 2005-10-12 23:39 UTC (History)
2 users (show)

See Also:
Host:
Target: powerpc-linux
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-10-11 19:34:34


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Schwab 2005-10-07 11:37:10 UTC
Instead of passing the pointer to the variable itself a pointer to a temporary holding the address of the variable is used.

$ cat wait.c
typedef union
{
  union wait *__uptr;
  int *__iptr;
} __WAIT_STATUS __attribute__ ((__transparent_union__));
union wait
{
  int w_status;
};
int wait (__WAIT_STATUS __status_loc);

int do_wait (void) { int status; wait (&status); return status; }
$ gcc -O2 -S -fverbose-asm wait.c
$ cat wait.s
	.file	"wait.c"

 # rs6000/powerpc options: -msdata=data -G 8
 # GNU C version 4.1.0 20051001 (experimental) (SUSE Linux) (powerpc64-suse-linux)
 #	compiled by GNU C version 4.1.0 20051001 (experimental) (SUSE Linux).
 # GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
 # options passed:  -iprefix -isystem -D__unix__ -D__gnu_linux__
 # -D__linux__ -Dunix -D__unix -Dlinux -D__linux -Asystem=linux
 # -Asystem=unix -Asystem=posix -auxbase -O2 -fverbose-asm
 # options enabled:  -falign-loops -fargument-alias -fbranch-count-reg
 # -fcaller-saves -fcommon -fcprop-registers -fcrossjumping
 # -fcse-follow-jumps -fcse-skip-blocks -fdefer-pop
 # -fdelete-null-pointer-checks -fearly-inlining
 # -feliminate-unused-debug-types -fexpensive-optimizations -ffunction-cse
 # -fgcse -fgcse-lm -fguess-branch-probability -fident -fif-conversion
 # -fif-conversion2 -finline-functions-called-once -fipa-pure-const
 # -fipa-reference -fipa-type-escape -fivopts -fkeep-static-consts
 # -fleading-underscore -floop-optimize -floop-optimize2 -fmath-errno
 # -fmerge-constants -fomit-frame-pointer -foptimize-register-move
 # -foptimize-sibling-calls -fpeephole -fpeephole2 -freg-struct-return
 # -fregmove -freorder-blocks -freorder-functions -frerun-cse-after-loop
 # -frerun-loop-opt -fsched-interblock -fsched-spec
 # -fsched-stalled-insns-dep -fschedule-insns -fschedule-insns2
 # -fshow-column -fsplit-ivs-in-unroller -fstrength-reduce
 # -fstrict-aliasing -fthread-jumps -ftrapping-math -ftree-ccp -ftree-ch
 # -ftree-copy-prop -ftree-copyrename -ftree-dce -ftree-dominator-opts
 # -ftree-dse -ftree-fre -ftree-loop-im -ftree-loop-ivcanon
 # -ftree-loop-optimize -ftree-lrs -ftree-pre -ftree-salias -ftree-sink
 # -ftree-sra -ftree-store-ccp -ftree-store-copy-prop -ftree-ter
 # -ftree-vect-loop-version -ftree-vrp -funit-at-a-time -fverbose-asm
 # -fzero-initialized-in-bss -m32 -maix-struct-return -mbig -mbig-endian
 # -mbss-plt -mfp-in-toc -mfused-madd -mhard-float -mnew-mnemonics
 # -mpowerpc -msched-prolog -mupdate

 # Compiler executable checksum: 98247ca61e462f7c754c17f0242fef41

	.section	".text"
	.align 2
	.p2align 4,,15
	.globl do_wait
	.type	do_wait, @function
do_wait:
	mflr 0	 #,
	stwu 1,-32(1)	 #,,
	stw 0,36(1)	 #,
	addi 3,1,24	 #,,
	addi 0,1,8	 # status.1,,
	stw 0,24(1)	 #, status.1
	bl wait	 #
	lwz 0,36(1)	 #,
	lwz 3,8(1)	 # status, <result>
	addi 1,1,32	 #,,
	mtlr 0	 #,
	blr	 #
	.size	do_wait,.-do_wait
	.ident	"GCC: (GNU) 4.1.0 20051001 (experimental) (SUSE Linux)"
	.section	.note.GNU-stack,"",@progbits
Comment 1 Andrew Pinski 2005-10-07 11:45:48 UTC
Hmm, unions are passed by reference in powerpc-linux, unless that is also an ABI regression too.
Comment 2 Andrew Pinski 2005-10-07 12:06:12 UTC
Confirmed, this is a ABI regression.
Comment 3 Andrew Pinski 2005-10-07 13:05:15 UTC
Debugging this, it looks a middle-end bug, in that we get the wrong type.

The type which we get now:
Breakpoint 5, function_arg (cum=0xbffff020, mode=SImode, type=0x1c97900, named=1) at ../../gcc/config/rs6000/rs6000.c:4940
4940      enum rs6000_abi abi = DEFAULT_ABI;
(gdb) p debug_tree(type)
 <pointer_type 0x1c97900
    type <union_type 0x1c8c540 type_0 SI
        size <integer_cst 0x1c094a0 constant invariant 32>
        unit size <integer_cst 0x1c09160 constant invariant 4>
        align 32 symtab 0 alias set 4
        fields <field_decl 0x1c23834 __uptr type <pointer_type 0x1c8c600>
            unsigned SI file t.c line 3 size <integer_cst 0x1c094a0 32> unit size <integer_cst 0x1c09160 4>
            align 32 offset_align 128
            offset <integer_cst 0x1c09180 constant invariant 0>
            bit offset <integer_cst 0x1c09960 constant invariant 0> context <union_type 0x1c8c540> chain <field_decl 0x1c23898 __iptr>> context <translation_unit_decl 0x1c71690 D.1302>
        pointer_to_this <pointer_type 0x1c97900> chain <type_decl 0x1c714d0 D.1287>>
    unsigned SI size <integer_cst 0x1c094a0 32> unit size <integer_cst 0x1c09160 4>
    align 32 symtab 0 alias set -1>
(gdb) p debug_generic_expr (type)
union 
{
  union wait * __uptrD.1289;
  intD.0 * __iptrD.1290;
} *


The type we got in 4.0.x:
(gdb) p debug_tree(type)
 <pointer_type 0x4147b3a0
    type <union_type 0x4147b2b8 wait type_0 SI
        size <integer_cst 0x414064a0 constant invariant 32>
        unit size <integer_cst 0x41406160 constant invariant 4>
        align 32 symtab 0 alias set -1
        fields <field_decl 0x4147b740 w_status type <integer_type 0x4140e488 int>
            SI file t.c line 8 size <integer_cst 0x414064a0 32> unit size <integer_cst 0x41406160 4>
            align 32 offset_align 128
            offset <integer_cst 0x41406180 constant invariant 0>
            bit offset <integer_cst 0x41406960 constant invariant 0> context <union_type 0x4147b2b8 wait> arguments <integer_cst 0x41406180 0>> context <translation_unit_decl 0x4147be80 D.1155>
        pointer_to_this <pointer_type 0x4147b3a0> chain <type_decl 0x4147b32c D.1140>>
    unsigned SI size <integer_cst 0x414064a0 32> unit size <integer_cst 0x41406160 4>
    align 32 symtab 0 alias set -1>
$1 = void
(gdb) p debug_generic_expr(type)
union wait *


This what we get in function_arg.
Comment 4 Andrew Pinski 2005-10-07 13:08:36 UTC
Caused by:

2005-09-24  Richard Henderson  <rth@redhat.com>
        ...
        * gimplify.c (create_tmp_from_val): Likewise.

Confirmed caused by that patch by reverting it.
Comment 5 GCC Commits 2005-10-11 22:52:09 UTC
Subject: Bug 24255

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	rth@gcc.gnu.org	2005-10-11 22:52:04

Modified files:
	gcc            : ChangeLog c-typeck.c 
Added files:
	gcc/testsuite/gcc.dg: transparent-union-5.c 

Log message:
	PR c/24255
	* c-typeck.c (convert_for_assignment): Use build_constructor_single
	to initialize a transparent union instead of a nop_expr.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.10140&r2=2.10141
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/c-typeck.c.diff?cvsroot=gcc&r1=1.481&r2=1.482
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/transparent-union-5.c.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 6 Richard Henderson 2005-10-11 23:38:43 UTC
Fixed.
Comment 7 Richard Henderson 2005-10-12 17:01:45 UTC
Not fixed.
Comment 8 GCC Commits 2005-10-12 23:34:15 UTC
Subject: Bug 24255

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	rth@gcc.gnu.org	2005-10-12 23:34:09

Modified files:
	gcc            : ChangeLog c-common.c function.c print-tree.c 
	                 tree-inline.c tree.h 
	gcc/doc        : extend.texi 

Log message:
	PR c/24255
	* tree.h (DECL_TRANSPARENT_UNION): Remove.
	* function.c (assign_parm_find_data_types): Don't support it.
	* print-tree.c (print_node): Likewise.
	* c-common.c (handle_transparent_union_attribute): Likewise.
	Use build_duplicate_type.
	* tree-inline.c (remap_type_1): Split out of remap_type;
	properly remap aggregate fields.
	(build_duplicate_type): New.
	* doc/extend.texi (Variable Attributes): Remove documentation
	for transparent_union.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.10151&r2=2.10152
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/c-common.c.diff?cvsroot=gcc&r1=1.654&r2=1.655
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/function.c.diff?cvsroot=gcc&r1=1.645&r2=1.646
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/print-tree.c.diff?cvsroot=gcc&r1=1.105&r2=1.106
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-inline.c.diff?cvsroot=gcc&r1=1.211&r2=1.212
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.h.diff?cvsroot=gcc&r1=1.758&r2=1.759
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/doc/extend.texi.diff?cvsroot=gcc&r1=1.268&r2=1.269

Comment 9 Richard Henderson 2005-10-12 23:39:55 UTC
Fixed, again