https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66795

--- Comment #2 from Andy Lutomirski <luto at kernel dot org> ---
(In reply to Andrew Pinski from comment #1)
> The code below is invalid as __builtin_frame_address is only for reading
> from the current frame.

If this code is invalid, then what exactly is valid code that uses
__builtin_frame_address?  This is way outside the scope of the C standard. 
Apparently one cannot reliably write to pointers derived from
__builtin_frame_address?  Can one reliably *read* them?

What I'm trying to do is actually the most well-defined think I can think of to
do with __builtin_frame_address.  Roughly:

__attribute__((externally_visible)) void func(void)
{
    unsigned long *ptr = (unsigned long *)__builtin_frame_address(0) - 2;
    *ptr = some_other_value;
}

pushq some_value
call func
; the top of the stack should now contain some_other_value

As it stands, gcc can't usefully compile this because the store is deleted.  

> Also -O2 enables -fomit-frame-pointer which might
> cause the frame pointer to go away.

It's the other way around.  Using __builtin_frame_address(0) prevents the frame
pointer from being omitted.  This is an unnecessary constraint, at least for my
use case.  If __builtin_frame_pointer(0) returned a pointer to the stack one
slot below the saved return address regardless of whether the frame pointer
exists, it would work for me.

Would it make sense to add a new, well-defined intrinsic that returns the
address of the current function's return address?  As long as the function is
noinline, this would have sensible semantics.  (Arguably it should be an error
to use such an intrinsic in a function that isn't either noinline or forcibly
inlined.)

Reply via email to