From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id F1C5938560A4; Wed, 7 Jun 2023 01:33:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F1C5938560A4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686101625; bh=3wLCiV+vbM9S4HSBb5HBDzVfLFtHhHVFPQy4EfhZ480=; h=From:To:Subject:Date:From; b=qoVahAguXAJt0VhNoehkYaHOWw0PPnDczLm39tJ7IjGZcXA6fZSPzztuK2Bu+eXgw etKFm5WejfVknCm8g+EeTPX0VpLCMqN5VW5HGuNaq9cjO90ZIr5K/ULCaMu3JWfzVl gT53Uyt91Mjloiyk7IRXycSi7PQv1KSDM9ptt09s= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-1594] c++: Add -Wnrvo X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/trunk X-Git-Oldrev: 7e0b65b239c3a0d68ce94896b236b03de666ffd6 X-Git-Newrev: 2ae5384d457b9c67586de012816dfc71a6943164 Message-Id: <20230607013345.F1C5938560A4@sourceware.org> Date: Wed, 7 Jun 2023 01:33:45 +0000 (GMT) List-Id: https://gcc.gnu.org/g:2ae5384d457b9c67586de012816dfc71a6943164 commit r14-1594-g2ae5384d457b9c67586de012816dfc71a6943164 Author: Jason Merrill Date: Tue Jun 6 12:46:26 2023 -0400 c++: Add -Wnrvo While looking at PRs about cases where we don't perform the named return value optimization, it occurred to me that it might be useful to have a warning for that. This does not fix PR58487, but might be interesting to people watching it. PR c++/58487 gcc/c-family/ChangeLog: * c.opt: Add -Wnrvo. gcc/ChangeLog: * doc/invoke.texi: Document it. gcc/cp/ChangeLog: * typeck.cc (want_nrvo_p): New. (check_return_expr): Handle -Wnrvo. gcc/testsuite/ChangeLog: * g++.dg/opt/nrv25.C: New test. Diff: --- gcc/doc/invoke.texi | 19 +++++++++++++++++++ gcc/c-family/c.opt | 4 ++++ gcc/cp/typeck.cc | 25 +++++++++++++++++++++++-- gcc/testsuite/g++.dg/opt/nrv25.C | 15 +++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9130104af22..6d08229ce40 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6678,6 +6678,25 @@ is only active when @option{-fdelete-null-pointer-checks} is active, which is enabled by optimizations in most targets. The precision of the warnings depends on the optimization options used. +@opindex Wnrvo +@opindex Wno-nrvo +@item -Wnrvo @r{(C++ and Objective-C++ only)} +Warn if the compiler does not elide the copy from a local variable to +the return value of a function in a context where it is allowed by +[class.copy.elision]. This elision is commonly known as the Named +Return Value Optimization. For instance, in the example below the +compiler cannot elide copies from both v1 and b2, so it elides neither. + +@smallexample +std::vector f() +@{ + std::vector v1, v2; + // ... + if (cond) return v1; + else return v2; // warning: not eliding copy +@} +@end smallexample + @opindex Winfinite-recursion @opindex Wno-infinite-recursion @item -Winfinite-recursion diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 3333cddeece..cead1995561 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -923,6 +923,10 @@ Wnamespaces C++ ObjC++ Var(warn_namespaces) Warning Warn on namespace definition. +Wnrvo +C++ ObjC++ Var(warn_nrvo) +Warn if the named return value optimization is not performed although it is allowed. + Wpacked-not-aligned C ObjC C++ ObjC++ Var(warn_packed_not_aligned) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall) Warn when fields in a struct with the packed attribute are misaligned. diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 11fcc7fcd3b..6b5705e806d 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -10670,6 +10670,16 @@ can_do_nrvo_p (tree retval, tree functype) && !TYPE_VOLATILE (TREE_TYPE (retval))); } +/* True if we would like to perform NRVO, i.e. can_do_nrvo_p is true and we + would otherwise return in memory. */ + +static bool +want_nrvo_p (tree retval, tree functype) +{ + return (can_do_nrvo_p (retval, functype) + && aggregate_value_p (functype, current_function_decl)); +} + /* Like can_do_nrvo_p, but we check if we're trying to move a class prvalue. */ @@ -11151,7 +11161,7 @@ check_return_expr (tree retval, bool *no_warning) bare_retval = tree_strip_any_location_wrapper (retval); } - bool named_return_value_okay_p = can_do_nrvo_p (bare_retval, functype); + bool named_return_value_okay_p = want_nrvo_p (bare_retval, functype); if (fn_returns_value_p && flag_elide_constructors) { if (named_return_value_okay_p @@ -11159,7 +11169,18 @@ check_return_expr (tree retval, bool *no_warning) || current_function_return_value == bare_retval)) current_function_return_value = bare_retval; else - current_function_return_value = error_mark_node; + { + if ((named_return_value_okay_p + || (current_function_return_value + && current_function_return_value != error_mark_node)) + && !warning_suppressed_p (current_function_decl, OPT_Wnrvo)) + { + warning (OPT_Wnrvo, "not eliding copy on return in %qD", + current_function_decl); + suppress_warning (current_function_decl, OPT_Wnrvo); + } + current_function_return_value = error_mark_node; + } } /* We don't need to do any conversions when there's nothing being diff --git a/gcc/testsuite/g++.dg/opt/nrv25.C b/gcc/testsuite/g++.dg/opt/nrv25.C new file mode 100644 index 00000000000..35c4a88a088 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv25.C @@ -0,0 +1,15 @@ +// PR c++/58487 +// { dg-additional-options -Wnrvo } + +struct A { + A() {} + A(const A&); +}; + +A test() { + A a, b; + if (true) + return a; + else + return b; // { dg-warning Wnrvo } +}