https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115718
Bug ID: 115718 Summary: Deficiencies in -Wnrvo Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arthur.j.odwyer at gmail dot com Target Milestone: --- Jason Turner recently did a video on `-Wnrvo` https://www.youtube.com/watch?v=PTCFddZfnXc and I noticed some deficiencies in GCC's handling of his very first example. Here's the example in Godbolt: https://godbolt.org/z/7z6naEhhK S f(bool b) { S s = S(1); S t = S(2); if (b) { return s; } else { return t; } } GCC complains: "not eliding copy on return in 'S f(bool)' [-Wnrvo]" Trivial defect #1: The message should say "move", not "copy". Bigger defect #2: No message is emitted for "return s", but in fact GCC doesn't elide the move on "return s" either! This is significant, because GCC *could* have elided the move on "return s" (by hoisting the test of the non-escaped bool `b` above the constructions of `s` and `t`); GCC simply chose not to elide it. So I would expect a warning there. Especially considering that the warning is disable-able: https://godbolt.org/z/56anKj4d3 Point #3: My Clang fork also implements something I've tentatively named "-Wnrvo", but it diagnoses only those situations where the programmer *specifically requested* NRVO via the [[clang::nrvo]] attribute on a return statement, and the compiler couldn't grant their request. This makes it feasible to turn on by default; although of course it also makes it far less discoverable/applicable, because it won't trigger on un-annotated codebases at all. Here's a side-by-side example: https://godbolt.org/z/fcK1b46c1 Point #4: Consider whether the point of this diagnostic is just to "debug" GCC's elision heuristic, or to be pedagogical. E.g. should it diagnose auto [s] = std::make_tuple(S(1)); return s; // this is a copy, no elision is possible or ChildOfS c; return c; // this is slicing, no elision is possible ? (Right now it does not diagnose either of these. But an average programmer might *think* that elision should apply to either or both of these cases, and appreciate the information that it does not.)