I'm attempting to use clang/llvm to compile some legacy C code, and am running into a strange issue. There are several functions in my codebase which make use of the __inline keyword, but do not include the customary static keyword along with it. When I compile these files, the generated code appears not to have any of the function definitions in it--just undefined references to external symbols. Specifically, if I have the following test program: __inline int foo() { return 5; } int bar() { return foo(); } Compiling for ARM with no optimizations yields this: 00000000 <bar>: 0: e92d4800 push {fp, lr} 4: e1a0b00d mov fp, sp 8: e24dd008 sub sp, sp, #8 c: ebfffffe bl 0 <foo> 10: e58d0004 str r0, [sp, #4] 14: e1a0d00b mov sp, fp 18: e8bd4800 pop {fp, lr} 1c: e12fff1e bx lr As you can see, no inlining took place, so there is still a reference to foo(). However, no definition for foo() is actually present. If I instead define foo as "static __inline", then the definition of foo() is retained: 00000000 <bar>: 0: e92d4800 push {fp, lr} 4: e1a0b00d mov fp, sp 8: e24dd008 sub sp, sp, #8 c: eb000003 bl 20 <foo> 10: e58d0004 str r0, [sp, #4] 14: e1a0d00b mov sp, fp 18: e8bd4800 pop {fp, lr} 1c: e12fff1e bx lr 00000020 <foo>: 20: e3a00005 mov r0, #5 24: e12fff1e bx lr Finally, if I compile with -O2, then in either case, inlining takes place and there's no problem: 00000000 <bar>: 0: e3a00005 mov r0, #5 4: e12fff1e bx lr I know there are some weird semantics among different compilers with the inline/__inline keywords in C when you don't pair them with static, but I can't imagine that this is correct. Is there a bug here, or am I missing something? Thanks, Matt
On Fri, Jul 6, 2012 at 3:39 PM, Matt Fischer <mattfischer84 at gmail.com> wrote:> I'm attempting to use clang/llvm to compile some legacy C code, and am > running into a strange issue. There are several functions in my > codebase which make use of the __inline keyword, but do not include > the customary static keyword along with it. When I compile these > files, the generated code appears not to have any of the function > definitions in it--just undefined references to external symbols. > > Specifically, if I have the following test program: > > __inline int foo() > { > return 5; > } > > int bar() > { > return foo(); > } > > Compiling for ARM with no optimizations yields this: > > 00000000 <bar>: > 0: e92d4800 push {fp, lr} > 4: e1a0b00d mov fp, sp > 8: e24dd008 sub sp, sp, #8 > c: ebfffffe bl 0 <foo> > 10: e58d0004 str r0, [sp, #4] > 14: e1a0d00b mov sp, fp > 18: e8bd4800 pop {fp, lr} > 1c: e12fff1e bx lr > > As you can see, no inlining took place, so there is still a reference > to foo(). However, no definition for foo() is actually present. > > If I instead define foo as "static __inline", then the definition of > foo() is retained: > > 00000000 <bar>: > 0: e92d4800 push {fp, lr} > 4: e1a0b00d mov fp, sp > 8: e24dd008 sub sp, sp, #8 > c: eb000003 bl 20 <foo> > 10: e58d0004 str r0, [sp, #4] > 14: e1a0d00b mov sp, fp > 18: e8bd4800 pop {fp, lr} > 1c: e12fff1e bx lr > > 00000020 <foo>: > 20: e3a00005 mov r0, #5 > 24: e12fff1e bx lr > > Finally, if I compile with -O2, then in either case, inlining takes > place and there's no problem: > > 00000000 <bar>: > 0: e3a00005 mov r0, #5 > 4: e12fff1e bx lr > > I know there are some weird semantics among different compilers with > the inline/__inline keywords in C when you don't pair them with > static, but I can't imagine that this is correct. Is there a bug > here, or am I missing something?No bug; those are the rules according to the C99 standard. You can force the old GNU inline semantics with "-std=gnu89", if that's what your code is expecting... -Eli
Hello> I know there are some weird semantics among different compilers with > the inline/__inline keywords in C when you don't pair them with > static, but I can't imagine that this is correct. Is there a bug > here, or am I missing something?Yes, clang is correct here, you're missing C99 inline semantics. You can either read C99 standard or http://clang.llvm.org/compatibility.html#inline -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University
Ah ok, guess I just didn't dig deep enough when reading up on this. Thanks for the explanation. On Fri, Jul 6, 2012 at 6:01 PM, Anton Korobeynikov <anton at korobeynikov.info> wrote:> Hello > >> I know there are some weird semantics among different compilers with >> the inline/__inline keywords in C when you don't pair them with >> static, but I can't imagine that this is correct. Is there a bug >> here, or am I missing something? > Yes, clang is correct here, you're missing C99 inline semantics. You > can either read C99 standard or > http://clang.llvm.org/compatibility.html#inline > > -- > With best regards, Anton Korobeynikov > Faculty of Mathematics and Mechanics, Saint Petersburg State University