Imagine:
S f(S a) {
return a;
}
Why is it not allowed to alias a and the return value slot?
S s = f(t);
S s
I feel, because the alternative is always available for the optimization:
S& f(S& a) { return a; } // pass & return by reference
^^^ ^^^
If f() is coded as mentioned in your example, then it's perfectly alright to assume that copy is intended or side effects are expected; otherwise why not to choose the pass/return by reference ?
Suppose if NRVO applies (as you ask) then there is no difference between S f(S) and S& f(S&)!
NRVO kicks in the situations like operator +() (example) because there is no worthy alternative.
One supporting aspect, all below function have different behaviors for copying:
S& f(S& a) { return a; } // 0 copy
S f(S& a) { return a; } // 1 copy
S f(S a) { A a1; return (...)? a : a1; } // 2 copies
In the 3rd snippet, if the (...) is known at compile time to be false then compiler generates only 1 copy.
This means, that compiler purposefully doesn't perform optimization when a trivial alternative is available.