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

Sean Silva via llvm-dev llvm-dev at lists.llvm.org
Mon Nov 30 22:23:29 PST 2015


On Mon, Nov 30, 2015 at 7:13 PM, Gao, Yunzhong via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> 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 think the wording "the function that is returned to" is referring to the
function that is dynamically returned to, not anything at source level.
It's more like "if you were to say `asm("ret")`, where would you return to"

Also see: See http://llvm.org/docs/LangRef.html#llvm-returnaddress-intrinsic

The "current function" is pretty much "whatever the backend sees". That
seems like the only reasonable way to define it.

-- Sean Silva


>
> 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
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151130/dbf6198f/attachment.html>


More information about the llvm-dev mailing list