[llvm-dev] Expected behavior of __builtin_return_address() with inlining?

Gao, Yunzhong via llvm-dev llvm-dev at lists.llvm.org
Mon Nov 30 19:13:07 PST 2015


Hi,
I am trying to understand what should be the expected behavior of __builtin_return_address(0)
when inlining has happened.

So, the GCC doc from https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html says:
(I used GCC doc because I could not find equivalent Clang/LLVM builtin doc)
  When inlining the expected behavior is that the function returns the address of the function
  that is returned to. To work around this behavior use the noinline function attribute.

I wrote the following test case to verify this behavior:
  /* test.c */
  long foo() {
    return (long)__builtin_return_address(0);
  }
  inline long bar() {
    return foo();
  }
  long foobar() {
    return bar();
  }
  /* end test.c */

My interpretation of the GCC doc is that, if foo() is inlined into bar(), then __builtin_return_address(0)
will return &bar, instead of the instruction address of the call to foo().

I compiled with GCC 4.8.2 and Clang 3.8.0, and I got the following result:

  # clang 3.8.0 trunk 253253
  # clang -S -O2 test.c
  foo:
    movq    (%rsp), %rax
    retq
  foobar:
    movq    (%rsp), %rax
    retq
  # end assembly

  # GCC 4.8.2-19ubuntu1
  # gcc -S -O2 test.c
  foo:
    movq    (%rsp), %rax
    ret
  bar:
    movq    (%rsp), %rax
    ret
  foobar:
    movq    (%rsp), %rax
    ret
  # end assembly

So with both compilers, an inlined __builtin_return_address(0) seems to produce the return address of the
function containing the callsite where the inlined function is expanded.

Maybe I misunderstood the documentation regarding the inlined __builtin_return_address()? Please help,

- Gao


More information about the llvm-dev mailing list