With this testcase: int foo (int (*cb)(void)) { return (*cb)(); } static int callback(void) { return 0; } int main (void) { int callback (void); return foo (callback); } On x86_64 with -fPIC, the address of callback as passed to foo is incorrect. If callback isn't static, it works (through the GOT). If the declaration of callback is removed it works (computes the address as %rip minus something). As written, it does a failed combination of the two. The result is that instead of passing callback's address, it loads the first 8 bytes at callback's address and passes those. (It also erroneously claims callback is unused, but I'm guessing that's a side-effect.) The code is questionable, but my reading of the standard says it's legal and that callback is still static after the (implicitly extern) declaration. % gcc-3.4.4 -O2 -fPIC -Wall -save-temps -o bug bug.c bug.c:2: warning: 'callback' defined but not used % gcc-3.4.4 -v Reading specs from /usr/local/lib/gcc/x86_64-pc-linux-gnu/3.4.4/specs Configured with: /tmp/src/gcc-3.4.4/configure --enable-languages=c,c++ --enable-version-specific-runtime-libs --disable-shared --enable-threads --with-gnu-as --with-gnu-ld --with-pic --host=x86_64-pc-linux-gnu Thread model: posix gcc version 3.4.4 [I bootstrapped this 3.4.4; it also fails with stock 3.4.3 from RedHat.]
Confirmed, only a 3.4 regression.
*** Bug 24106 has been marked as a duplicate of this bug. ***
*** Bug 26271 has been marked as a duplicate of this bug. ***
IIRC this was fixed by a latter rewrite of c-decl.c and most likely not going to be fixed for 3.4.x.
Fixed in 4.0.0 and up.