rjmccall wrote:

I agree that the standard does not appear to permit this in C.  There are three 
ways to fix this:
1. Disable NRVO in the callee just in case the address being initialized is 
aliased.
2. Disable RVO in the caller when aliasing is possible.
3. Convince the committee that they should change the standard to permit these 
simple optimizations.

(1) also requires disabling copy elision in some cases.  It is not possible to 
directly observe the address of the compound literal in `return (struct S) { 
E1, E2 };`, as the other example does, but E1 or E2 might assign to a field of 
the alias, and such modifications must be overwritten when the return occurs.

It is tractable to implement (2) with a simple local escape analysis of the 
variable's initializer.  This would *not* be tractable if the initialized 
variable were a global variable, but, fortunately, C does not permit global 
variables to be initialized with non-constant expressions.

(3) would presumably take the form of either permitting objects to overlap in 
certain situations, the same way that C++ permits copy elision, or just 
generally weakening object overlap rules during initialization.

Richard, I'm sorry to contradict you, but Aaron is correct to guess that this 
is ABI-affecting: ABIs should and sometimes do specify whether an indirect 
return address is allowed to be aliased.  For example, the x86_64 psABI is 
quite clear:

> If the type has class MEMORY, then the caller provides space for the return 
> value and passes the address of this storage in %rdi as if it were the first 
> argument to the function. In effect, this address becomes a “hidden” first 
> argument. This storage must not overlap any data visible to the callee 
> through other names than this argument.

So on x86_64, we are clearly required to at least do (2).  I don't think we 
want different rules on different targets unless we're forced to.

If (2) is implemented correctly, I believe there's no way to observe NRVO, so 
we don't also need to implement (1).

https://github.com/llvm/llvm-project/pull/101038
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to