https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120822
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- They're both redundant. In both cases the return operand is treated as an rvalue. For fb() the std::move defeats copy elision, so actually pessimizes the code. For fa() it's just redundant, because b will be treated as an rvalue and so the return value will be move constructed from static_cast<A&&>(b) automatically, without a std::move.