Output from "g++ -v": Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux Thread model: posix gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-20) Compile the following code using "g++ -S bug.c": ---8<---bug.c------------------------------------------8<--- struct Foo { int __attribute__((regparm(3))) (*p)(int); }; extern struct Foo *foo; extern const struct Foo *bar; int baz(int i) { return (foo->p)(i); } int zip(int i) { return (bar->p)(i); } ---8<--------------------------------------------------8<--- The only difference between baz() and zip() is that baz() uses a "struct Foo *" while zip() uses a "const struct Foo *". However, in the generated assembler code, baz() passes parameters in registers as requested, and zip() doesn't. _Z3bazi: [...] movl foo, %eax movl (%eax), %edx movl 8(%ebp), %eax call *%edx _Z3zipi: [...] movl bar, %eax pushl 8(%ebp) movl (%eax), %eax call *%eax Note: This bug is specific to the C++ compiler; the C compiler does the right thing.
Confirmed in 3.2.3 and 3.3.3 but fixed already in 3.4.0 but this is a regression from 3.0.4.
won't fix for 3.3.6. Works in 3.4.0 and higher.