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

--- Comment #8 from Jason Merrill <jason at gcc dot gnu.org> ---
(In reply to Jason Merrill from comment #6)
> (In reply to Jonathan Wakely from comment #5)
> > (In reply to Jan Hubicka from comment #4)
> > > What about escape bits? Is it OK to save the address to global memory
> > > and then check it in the destructor?
> > 
> > Yes, but does that matter? After the function returns the pointer is invalid
> > and can't be used for anything. It's just an invalid pointer value that
> > happens to be correctly aligned for the parameter type.
> 
> To be precise, in our implementation the pointer is invalid after the end of
> the full-expression that contains the call (implementation-defined per
> https://eel.is/c++draft/expr.call#6).

However, we don't support something like

struct A
{
  int i;
  A(int i): i(i) { }
  A(const A& a): i(a.i) { } // force pass by invisiref
  int val() { return i; }
};

A& f(A a)
{
  return a;
}

int main()
{
  return f(42).val();
}

because cp_gimplify_r (since GCC 5) changes a return of a local variable
address to return null instead, and the call to val segfaults.  Clang and EDG
return 42.  Without the user-provided copy constructor, it fails on all
compilers because there's no invisiref, the parameter actually lives in the
callee.

I suspect we're wrong here, though this is of course extremely dubious code.

Reply via email to