From patchwork Wed Jun 7 01:33:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 70690 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D3AAF3856625 for ; Wed, 7 Jun 2023 01:33:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D3AAF3856625 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1686101616; bh=ikU+Mic4/9RydAK9eK+jZs2fo5MznHiA/BoiRpL5mW8=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=R9/I8DgCt/Qy9ucr1gXByCZeeYtIdS5zzspwrp68M/90+6Jczo0OdEVCJ607+t+wz OAObND0OxgZWTga51zKMvPtRWiUy6kHnebCG30xMQeeuXIOSckMGARxYADqcySoEyg L6gnIX1242FU+a6HGAMENTjTAtMN8u5whGxR9zbw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 9182D38582BC for ; Wed, 7 Jun 2023 01:33:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9182D38582BC Received: from mail-qk1-f197.google.com (mail-qk1-f197.google.com [209.85.222.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-128-js8DtYX0PnatQJZ4FlAUCA-1; Tue, 06 Jun 2023 21:33:07 -0400 X-MC-Unique: js8DtYX0PnatQJZ4FlAUCA-1 Received: by mail-qk1-f197.google.com with SMTP id af79cd13be357-75d558057f6so470778385a.3 for ; Tue, 06 Jun 2023 18:33:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686101586; x=1688693586; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ikU+Mic4/9RydAK9eK+jZs2fo5MznHiA/BoiRpL5mW8=; b=SFBs8CQuMxYuVvWVepDq3gVfOfDzcmwcMs/PMGb7HpxzD1jJEjN0hqEW3QoYQ2VJkb WOOUB3BbX087iiZrAmYBw84vwFLwxiKGIlMEZ0wG4G7NNu/ieCyfNLzVBOswMrjxMBu0 1UwMHp/13QPlwa6naXBktzGWOxZtklFLkyTEpi6Vj60cWBiG9E2nzI2R/BH4QMYWCCDW oK52HeDXS8l8sQLGJXXQMH5sKFRm0ZuJTd+0dSAjnLD/Xrz3uUyPGGjLIZIGS5pWCcty VO0oFsgWk6Et8TKkZTj7vDcWV++PmM9xlXoU+gitOr5zFqEDhdyQ9clkMNMcdkJvKSwl yoEQ== X-Gm-Message-State: AC+VfDxqJlzkF71v+y2AaeNj9M3ZK+V7nYAXAlWHIOQxR2JXUQS7jmOH t3yqkemtferzkcELDE2ZJgY/Q7jA1U8sr6HYEy6uGIF5VN+61BMZTLfETZnqvZufM6rpiSqCUQS /y7I0bdUUGc6oauZngY/BgdpLBmCe+inYLfbhEiVRxa6kPeU0qJo4upE3LuIK3LKWzcW7G7QIgQ == X-Received: by 2002:a37:43c5:0:b0:75b:23a1:467 with SMTP id q188-20020a3743c5000000b0075b23a10467mr418208qka.45.1686101586213; Tue, 06 Jun 2023 18:33:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6/Hisc2OMoiAZD0m918swyJr4oapGbkj8WtChpmzrhh5qSg4Q2jCSZlq9QUuxJoRW3Oxc1MQ== X-Received: by 2002:a37:43c5:0:b0:75b:23a1:467 with SMTP id q188-20020a3743c5000000b0075b23a10467mr418199qka.45.1686101585758; Tue, 06 Jun 2023 18:33:05 -0700 (PDT) Received: from jason.com (130-44-146-16.s12558.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.146.16]) by smtp.gmail.com with ESMTPSA id f16-20020a05620a12f000b0075ca4cd03d4sm5294496qkl.64.2023.06.06.18.33.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Jun 2023 18:33:05 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: Add -Wnrvo Date: Tue, 6 Jun 2023 21:33:03 -0400 Message-Id: <20230607013303.2771541-1-jason@redhat.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jason Merrill via Gcc-patches From: Jason Merrill Reply-To: Jason Merrill Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< -- 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. --- 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(-) create mode 100644 gcc/testsuite/g++.dg/opt/nrv25.C base-commit: 29c82c6ca929e0f5eccfe038dea71177d814c6b7 prerequisite-patch-id: aed53cdac161144c31cb1433282e1ad1d49d3770 prerequisite-patch-id: 1098cb4457a5eff90fa8176f9b0d8d2e9477596e prerequisite-patch-id: 823f2ce422455c6c7ccbaa9938b670a600b376df prerequisite-patch-id: 964ab37ff6b24b8fbdc942ff338100c5f5ee6a59 prerequisite-patch-id: fadb6db55b6de5d7d467edeb485770af9f9e0772 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 } +}