Problem with __inline keyword

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

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

Ah ok, guess I just didn't dig deep enough when reading up on this.
Thanks for the explanation.