Even when compiling with -O0, GCC uses non-standard parameter passing conventions for static inline functions, which makes debugging difficult. In this case, the function of interest converts a tagged value to a pointer; it's very helpful to be able to use this in GDB 'print' commands. In the assembly code shown, notice that the function is expecting to find its argument in %eax, even though the standard IA-32 calling conventions pass the first argument on the stack. The GDB session also demonstrates this. $ (cd ~/gcc/gcc; svn info) Path: . URL: svn://gcc.gnu.org/svn/gcc/trunk Repository Root: svn://gcc.gnu.org/svn/gcc Repository UUID: 138bc75d-0d04-0410-961f-82ee72b054a4 Revision: 144927 Node Kind: directory Schedule: normal Last Changed Author: gccadmin Last Changed Rev: 144927 Last Changed Date: 2009-03-17 17:16:40 -0700 (Tue, 17 Mar 2009) $ cat jsobj.i extern "C" { static inline struct JSObject *JSVAL_TO_OBJECT (int v) { return (struct JSObject *) (v & ~3); } } static int obj_toSource (int *vp) { JSVAL_TO_OBJECT (vp[0]); } int main(int argc, char **argv) { } $ c++ -v -O0 -g jsobj.i -o jsobj -save-temps Using built-in specs. Target: i686-pc-linux-gnu Configured with: ../gcc/configure --prefix=/home/jimb/gcc --enable-languages=c,c++ Thread model: posix gcc version 4.4.0 20090318 (experimental) (GCC) COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'jsobj' '-save-temps' '-shared-libgcc' '-mtune=generic' /home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/cc1plus -fpreprocessed jsobj.i -quiet -dumpbase jsobj.i -mtune=generic -auxbase jsobj -g -O0 -version -o jsobj.s GNU C++ (GCC) version 4.4.0 20090318 (experimental) (i686-pc-linux-gnu) compiled by GNU C version 4.4.0 20090318 (experimental), GMP version 4.2.2, MPFR version 2.3.2. GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096 Compiler executable checksum: 00b593c3c99bbacc875575ff2b6655cc COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'jsobj' '-save-temps' '-shared-libgcc' '-mtune=generic' as -V -Qy -o jsobj.o jsobj.s GNU assembler version 2.18.93 (i486-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.18.93.20081009 COMPILER_PATH=/home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/:/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/ LIBRARY_PATH=/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/:/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-O0' '-g' '-o' 'jsobj' '-save-temps' '-shared-libgcc' '-mtune=generic' /home/jimb/gcc/libexec/gcc/i686-pc-linux-gnu/4.4.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o jsobj /usr/lib/crt1.o /usr/lib/crti.o /home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/crtbegin.o -L/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0 -L/home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/../../.. jsobj.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /home/jimb/gcc/lib/gcc/i686-pc-linux-gnu/4.4.0/crtend.o /usr/lib/crtn.o $ cat jsobj.s ... JSVAL_TO_OBJECT: .LFB0: .file 1 "jsobj.i" .loc 1 4 0 .cfi_startproc .cfi_personality 0x0,__gxx_personality_v0 pushl %ebp .cfi_def_cfa_offset 8 movl %esp, %ebp .cfi_offset 5, -8 .cfi_def_cfa_register 5 subl $4, %esp movl %eax, -4(%ebp) .loc 1 5 0 movl -4(%ebp), %eax andl $-4, %eax .loc 1 6 0 leave ret ... $ gdb jsobj GNU gdb (GDB) 6.8.50.20090106-cvs Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... (gdb) start Temporary breakpoint 1 at 0x804844c: file jsobj.i, line 16. Starting program: /home/jimb/mc/b/static-call/jsobj Temporary breakpoint 1, main (argc=1, argv=0xbffff8a4) at jsobj.i:16 16 } Current language: auto; currently c++ (gdb) set $eax = 0x42424242 (gdb) print JSVAL_TO_OBJECT(0x53535353) $1 = (struct JSObject *) 0x42424240 (gdb) quit The program is running. Quit anyway (and kill it)? (y or n) y $
Created attachment 17490 [details] Test case This is the same test case used in the transcript; attached just for convenience.
"even though the standard IA-32 calling conventions pass the first argument on the stack" I thought this was disabled at -O0. At -O1 this should be enabled.
Confirmed. In 3.3 this worked (was probably not implemented).
/* Use register calling convention for local functions when possible. */ if (decl && TREE_CODE (decl) == FUNCTION_DECL && !profile_flag) That should include !optimize I think.
We used to check flag_unit_at_a_time in this function: /* Use register calling convention for local functions when possible. */ if (decl && TREE_CODE (decl) == FUNCTION_DECL && flag_unit_at_a_time && !profile_flag) Which meant it never worked for C++ in 3.4 and above , for C, it always worked until 4.4 which removed the check.
Created attachment 17491 [details] gcc44-pr39496.patch && optimize, not !optimize. Here is what I'm going to bootstrap/regtest.
Subject: Bug 39496 Author: jakub Date: Thu Mar 19 10:25:43 2009 New Revision: 144955 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=144955 Log: PR target/39496 * config/i386/i386.c (ix86_function_regparm): Don't optimize local functions using regparm calling conventions when not optimizing. (ix86_function_sseregparm): Similarly for sseregparm calling conventions. * gcc.target/i386/pr39496.c: New test. * g++.dg/other/pr39496.C: New test. Added: trunk/gcc/testsuite/g++.dg/other/pr39496.C trunk/gcc/testsuite/gcc.target/i386/pr39496.c Modified: trunk/gcc/ChangeLog trunk/gcc/config/i386/i386.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk so far.
Fixed for me in r144969. Thank you all!
Closing 4.2 branch.
This is worth fixing for 4.3.4. I am testing a backport.
Fixed.
Subject: Bug 39496 Author: rguenth Date: Wed Apr 22 15:01:45 2009 New Revision: 146583 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=146583 Log: 2009-04-22 Richard Guenther <rguenther@suse.de> Backport from mainline: PR target/39496 * config/i386/i386.c (ix86_function_regparm): Don't optimize local functions using regparm calling conventions when not optimizing. (ix86_function_sseregparm): Similarly for sseregparm calling conventions. * gcc.target/i386/pr39496.c: New test. * g++.dg/other/pr39496.C: New test. Added: branches/gcc-4_3-branch/gcc/testsuite/g++.dg/other/pr39496.C - copied unchanged from r144955, trunk/gcc/testsuite/g++.dg/other/pr39496.C branches/gcc-4_3-branch/gcc/testsuite/gcc.target/i386/pr39496.c - copied unchanged from r144955, trunk/gcc/testsuite/gcc.target/i386/pr39496.c Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/config/i386/i386.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog