Como o compilador sabe mover variáveis locais?
Estou curioso para saber exatamente como esse recurso funciona. Considere algo como
std::unique_ptr<int> f() { std::unique_ptr<int> lval(nullptr); return lval; }
Este código compila bem até mesmo para um tipo só de movimento, como o compilador o move implicitamente. Mas logicamente, para qualquer expressão de retorno, determinar se o resultado se refere ou não a uma variável local seria resolver o problema de parada e se o compilador simplesmente tratasse todas as variáveis locais como rvalues na expressão de retorno, isso seria problemático como a variável pode ser referido nessa expressão várias vezes. Mesmo se um local tivesse apenas umdireto referência, você não seria capaz de provar que não tinha outros aliases indiretos.
Então, como o compilador sabe quando mover da expressão de retorno?