Can compiler generate std::move for a last use of lvalue automatically?

c++, c++11, rvalue-reference

Solution

No. Consider:

using X = std::shared_ptr<int>;
void g(X);
void f() {
    X b = std::make_shared<int>();
    int &i = *b;
    g(b);              // last use of 'b'
    i = 5;
}

In general, the compiler cannot assume that altering the semantics of copies, moves and destructors of `X` will be a legitimate change without performing analysis on all the code surrounding the use of `b` (i.e., the whole of `f`, `g`, and all the types used therein).

Indeed, in some cases whole-program analysis may be necessary:

using X = std::shared_ptr<std::lock_guard<std::mutex>>;
std::mutex i_mutex;
int i;
void g(X);
void f() {
    X b = std::make_shared<std::lock_guard<std::mutex>>(i_mutex);
    g(b);              // last use of 'b'
    i = 5;
}

If `b` is moved, this introduces a data race against other threads that synchronize access to `i` using `i_mutex`.

Problem

A code like this is often seen in r-value references articles: Dave Abrams: Move It With Rvalue References ``` void g(X); void f() { X b; g(b); // still need the value of b … g( std::move(b) ); // all done with b now; grant permission to move } ``` Could a compiler generate this optimization automatically, i.e. to detect a l-value is going to be destructed anyway and could be moved from, or would this be a violation of the standard, assuming a generic case the compiler does not know anything about how is move, copy or destruct implemented for the X class? If such optimization is allowed, is it performed by some compiler in practice?

Original source