http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46596
Summary: misbehavior when mixing always_inline and alias attributes in the same compilation unit Product: gcc Version: 4.5.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: vap...@gentoo.org i have a function "foo". its header sets up an always_inline function that does sanity checks when constants are involved. otherwise it delays the non-constant checking to another function. here is the portion from the header: extern void foo(int i); extern void __in(int i); extern inline __attribute__((always_inline)) void foo(int i) { __in(i); } where i actually define "foo", there is an alias used to setup multiple symbols. also in that file is another function which calls the inline checking function. together, gcc barfs. here is the portion of the file: void bar(int i) { foo(i + 1234); } void __foo(int i) {} extern typeof(__foo) foo __attribute__((alias("__foo"))); combine them into one and compile like so (this is 4.5.1): gcc -O2 -c test.c -std=gnu99 -fgnu89-inline -Winline this produces the error: test.c: In function ‘bar’: test.c:18:22: sorry, unimplemented: inlining failed in call to ‘foo’: function body not available test.c:14:5: sorry, unimplemented: called from here that doesnt seem right since the function body *is* available. if i split the __foo/foo definitions into their own dedicated file, then everything compiles just fine as i'd expect. what's even more odd though is that -Winline affects code generation. if you compile without that flag, you dont get any errors, but the generated code is wrong: gcc -O2 -c test.c -std=gnu99 -fgnu89-inline objdump -dr test.o ... 0000000000000000 <bar>: 0: 81 c7 d2 04 00 00 add $0x4d2,%edi 6: e9 00 00 00 00 jmpq b <bar+0xb> 7: R_X86_64_PC32 foo-0x4 b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) ... clearly it's just jumping straight to the definition of foo rather than going through the inline function. doesnt seem to be a regression ... every gcc version ive tested fails in the same way: 4.0.4, 4.1.2, 4.2.4, 4.3.5, 4.4.4, 4.5.1. versions before 4.2.x had the -fgnu89-inline flag dropped since that was the default behavior and so was unnecessary (and unrecognized).