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
Hmm, unions are passed by reference in powerpc-linux, unless that is also an ABI regression too.
Confirmed, this is a ABI regression.
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.
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.
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
Fixed.
Not fixed.
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
Fixed, again