From patchwork Fri Aug 2 19:22:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1968495 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=TEAcKXX+; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WbG1h00xwz1yZl for ; Sat, 3 Aug 2024 05:22:31 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3A6A43858D3C for ; Fri, 2 Aug 2024 19:22:30 +0000 (GMT) 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 ESMTP id 708F03858D20 for ; Fri, 2 Aug 2024 19:22:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 708F03858D20 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 708F03858D20 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722626529; cv=none; b=IfG+1KP9Bg3SL6EJUiONedRoW2+DreYMezQ0+uhZg3xOTPBQK/R23mEV8T+lGfQolIVKUl3Mi2TVopjmWE363NEQBYsiCVyaepF30NfxRUOGpMhjeLkGEkcpgnpaFMn26JeacKx26NYDj1w4Xd6SD84wmoqTy0aLEMTrvFmVPpc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722626529; c=relaxed/simple; bh=AhM8gyD3xPcJjNG/zNjM/L3Wmmp/YHVDTWIitgId0Lo=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=e2eM/KqBqYvCVG19BdRyB1llELcNLBTiPaFCgEGaNNG8SwjDdOMVz/TA2sLTv36CnLs3NpND+T2OW0aeyOIbX4ZM/lOzkSUWC0W73FsKhEHu0r613TgPcJ6KU7v6Rl/vAqPjSMS1/uNPY3xqlyJdXjzwiPCWe1YuvxFGqKl9oww= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1722626527; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Wuw1va1rgI5wv0L+pj0Pj83dFWFP8V32Jkp9JIXgRhI=; b=TEAcKXX+0Vy612z8Qx1cMwBbZa9AT/3Ujxh0YhSKWLaux6sLVHnuOKlo0ASu6f3Qu0nnhH yiW25OEEdQtEUonLRIvOxMLSJ68nft8VSXag6wi9uQ/dtdViobI590XUSwXoT8WiDsN4Ve WKTeHZ3I41J66GysOv/DT2KdYfAUe1s= Received: from mail-oi1-f200.google.com (mail-oi1-f200.google.com [209.85.167.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-688-bokaYpLjOuuY6SjYXRnw0A-1; Fri, 02 Aug 2024 15:22:05 -0400 X-MC-Unique: bokaYpLjOuuY6SjYXRnw0A-1 Received: by mail-oi1-f200.google.com with SMTP id 5614622812f47-3db15a91870so7105485b6e.0 for ; Fri, 02 Aug 2024 12:22:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722626525; x=1723231325; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Wuw1va1rgI5wv0L+pj0Pj83dFWFP8V32Jkp9JIXgRhI=; b=sf2NP81UlD5G1KWsifVVHw2FnE+XqhwJXy23v5heEzWHqt9be2owUtk96CZ0TwJ/bg V2zMHws4MgJV6NmOuSLnqWa3AisnqcN01Ztf7MPMAxvPiVwoBpXRFMCTpKmxuilO319B R71rZLOXpRwzQxLxl7LMvhqu7SK4pOW3acOae8wlsgABoWE7wxl+JdRIA4etZEM2ynr1 U3MyWvyzbI1VUdrQI98/zt56Ztvmc27ZVXl2JVwCQc3/wH/e7xtVTFgrKg62CBFBIKex ccR73+HC0xoCgt3I6x0MjIizSiqvhInBV9gBMopqHC0BqWVpsJqJ2LGNaPD737Dwh7Vw hJig== X-Gm-Message-State: AOJu0YwnZ7KDyduoVQQQTtPKB9ejXJ1KMlspk/WuM1oAwJyDdKjjC8Ul ddgvXny984RoKa46PuynO1OH6sttsMXet4htLlqJ0OFM8lonPVORsRF4h5I9q0aI81rcU0bqyMW KXg962m1wvrS0z8ZgHkt3USwZcgQmg/GSAZhZDfPJOUNTiRXN3Jp2uTw= X-Received: by 2002:a05:6808:1709:b0:3d9:21bb:170d with SMTP id 5614622812f47-3db55809ca8mr5577462b6e.16.1722626525078; Fri, 02 Aug 2024 12:22:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHanHEduo9UgIQEI9DRHQ0fEFp0C4tXq//d5o3KnmUtHlrwAzDI7gOzPr7TAYir//Po1EDPPg== X-Received: by 2002:a05:6808:1709:b0:3d9:21bb:170d with SMTP id 5614622812f47-3db55809ca8mr5577433b6e.16.1722626524536; Fri, 02 Aug 2024 12:22:04 -0700 (PDT) Received: from redhat.com ([2603:7000:9500:34a5::1db4]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-4518a6c46d2sm9560561cf.23.2024.08.02.12.22.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Aug 2024 12:22:04 -0700 (PDT) Date: Fri, 2 Aug 2024 15:22:02 -0400 From: Marek Polacek To: Jason Merrill Cc: GCC Patches Subject: [PATCH v2] c++: fix -Wdangling-reference false positive [PR115987] Message-ID: References: <20240801201959.3945190-1-polacek@redhat.com> MIME-Version: 1.0 In-Reply-To: User-Agent: Mutt/2.2.12 (2023-09-09) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org On Thu, Aug 01, 2024 at 05:20:43PM -0400, Jason Merrill wrote: > On 8/1/24 4:19 PM, Marek Polacek wrote: > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > -- >8 -- > > This fixes another false positive. When a function is taking a > > temporary of scalar type that couldn't be bound to the return type > > of the function, don't warn, such a program would be ill-formed. > > > > Thanks to Jonathan for reporting the problem. > > > > PR c++/115987 > > > > gcc/cp/ChangeLog: > > > > * call.cc (do_warn_dangling_reference): Don't consider a > > temporary with a scalar type that cannot bind to the return type. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/warn/Wdangling-reference22.C: New test. > > --- > > gcc/cp/call.cc | 15 +++++++++++++-- > > .../g++.dg/warn/Wdangling-reference22.C | 19 +++++++++++++++++++ > > 2 files changed, 32 insertions(+), 2 deletions(-) > > create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-reference22.C > > > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > > index 40cb582acc7..375256ebcc4 100644 > > --- a/gcc/cp/call.cc > > +++ b/gcc/cp/call.cc > > @@ -14290,8 +14290,19 @@ do_warn_dangling_reference (tree expr, bool arg_p) > > /* Recurse to see if the argument is a temporary. It could also > > be another call taking a temporary and returning it and > > initializing this reference parameter. */ > > - if (do_warn_dangling_reference (arg, /*arg_p=*/true)) > > - return expr; > > + if ((arg = do_warn_dangling_reference (arg, /*arg_p=*/true))) > > + { > > + /* If we know the temporary could not bind to the return type, > > + don't warn. This is for scalars only because for classes > > + we can't be sure we are not returning its sub-object. */ > > + if (SCALAR_TYPE_P (TREE_TYPE (arg)) > > + && TYPE_REF_P (rettype) > > + && SCALAR_TYPE_P (TREE_TYPE (rettype)) > > I don't think we need to check for scalar return type, only argument type. Oh that was a late change to keep attr-no-dangling6.C working, i.e., to keep warning for something like struct X { X(int); }; const X& get (const int& i) { return i; } void test () { [[maybe_unused]] const X& x2 = get (10); } But we already emit a -Wreturn-local-addr warning there. So, I've dropped the SCALAR_TYPE_P check and adjusted attr-no-dangling6.C instead: Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? -- >8 -- This fixes another false positive. When a function is taking a temporary of scalar type that couldn't be bound to the return type of the function, don't warn, such a program would be ill-formed. Thanks to Jonathan for reporting the problem. PR c++/115987 gcc/cp/ChangeLog: * call.cc (do_warn_dangling_reference): Don't consider a temporary with a scalar type that cannot bind to the return type. gcc/testsuite/ChangeLog: * g++.dg/ext/attr-no-dangling6.C: Adjust. * g++.dg/ext/attr-no-dangling7.C: Likewise. * g++.dg/warn/Wdangling-reference22.C: New test. --- gcc/cp/call.cc | 14 ++++++++++-- gcc/testsuite/g++.dg/ext/attr-no-dangling6.C | 22 +++++++++---------- gcc/testsuite/g++.dg/ext/attr-no-dangling7.C | 8 +++---- .../g++.dg/warn/Wdangling-reference22.C | 19 ++++++++++++++++ 4 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-reference22.C base-commit: 5ebfaf2d4994c124ce81aa0abd7eaa1529644749 diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 40cb582acc7..a75e2e5e3af 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -14290,8 +14290,18 @@ do_warn_dangling_reference (tree expr, bool arg_p) /* Recurse to see if the argument is a temporary. It could also be another call taking a temporary and returning it and initializing this reference parameter. */ - if (do_warn_dangling_reference (arg, /*arg_p=*/true)) - return expr; + if ((arg = do_warn_dangling_reference (arg, /*arg_p=*/true))) + { + /* If we know the temporary could not bind to the return type, + don't warn. This is for scalars only because for classes + we can't be sure we are not returning its sub-object. */ + if (SCALAR_TYPE_P (TREE_TYPE (arg)) + && TYPE_REF_P (rettype) + && !reference_related_p (TREE_TYPE (arg), + TREE_TYPE (rettype))) + continue; + return expr; + } /* Don't warn about member functions like: std::any a(...); S& s = a.emplace({0}, 0); diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C index 235a5fd86c5..5b349e8e682 100644 --- a/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C +++ b/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C @@ -12,26 +12,26 @@ struct SF { static constexpr bool value = false; }; template [[gnu::no_dangling(T::value)]] -const X& get (const int& i) +const X& get (const int& i, const X&) { return i == 0 ? x1 : x2; } template [[gnu::no_dangling(B)]] -const X& foo (const int& i) +const X& foo (const int& i, const X&) { return i == 0 ? x1 : x2; } [[gnu::no_dangling(val ())]] -const X& bar (const int& i) +const X& bar (const int& i, const X&) { return i == 0 ? x1 : x2; } [[gnu::no_dangling(!val ())]] -const X& baz (const int& i) +const X& baz (const int& i, const X&) { return i == 0 ? x1 : x2; } @@ -52,13 +52,13 @@ auto gety() -> Span; void test () { - [[maybe_unused]] const X& x1 = get (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x2 = get (10); // { dg-warning "dangling" } - [[maybe_unused]] const X& x3 = foo (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x4 = foo (10); // { dg-warning "dangling" } - [[maybe_unused]] const X& x7 = foo<> (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x5 = bar (10); // { dg-bogus "dangling" } - [[maybe_unused]] const X& x6 = baz (10); // { dg-warning "dangling" } + [[maybe_unused]] const X& x1 = get (10, X{}); // { dg-bogus "dangling" } + [[maybe_unused]] const X& x2 = get (10, X{}); // { dg-warning "dangling" } + [[maybe_unused]] const X& x3 = foo (10, X{}); // { dg-bogus "dangling" } + [[maybe_unused]] const X& x4 = foo (10, X{}); // { dg-warning "dangling" } + [[maybe_unused]] const X& x7 = foo<> (10, X{}); // { dg-bogus "dangling" } + [[maybe_unused]] const X& x5 = bar (10, X{}); // { dg-bogus "dangling" } + [[maybe_unused]] const X& x6 = baz (10, X{}); // { dg-warning "dangling" } [[maybe_unused]] const auto &b1 = geti()[0]; // { dg-bogus "dangling" } [[maybe_unused]] const auto &b2 = gety()[0]; // { dg-warning "dangling" } diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C b/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C index 3c392ed409f..a5fb809e6bd 100644 --- a/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C +++ b/gcc/testsuite/g++.dg/ext/attr-no-dangling7.C @@ -16,16 +16,16 @@ const X& foo(const int& i); bool val () { return true; } [[gnu::no_dangling(val ())]] // { dg-error "call" } -const X& bar (const int& i); +const X& bar (const int& i, const X&); -[[gnu::no_dangling(20)]] const X& fn1 (const int &); +[[gnu::no_dangling(20)]] const X& fn1 (const int &, const X&); void test () { - [[maybe_unused]] const X& x1 = bar (10); // { dg-warning "dangling" } + [[maybe_unused]] const X& x1 = bar (10, X{}); // { dg-warning "dangling" } [[maybe_unused]] const X& x2 = foo (10); // { dg-error "no matching" } [[maybe_unused]] const X& x3 // { dg-warning "dangling" } - = fn1 (10); // { dg-error "narrowing" } + = fn1 (10, X{}); // { dg-error "narrowing" } } diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference22.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference22.C new file mode 100644 index 00000000000..0381f9313fb --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference22.C @@ -0,0 +1,19 @@ +// PR c++/115987 +// { dg-do compile { target c++11 } } +// { dg-options "-Wdangling-reference" } + +template +struct Wrapper { + T val; +}; + +template + const T& unwrap_2(const Wrapper& r, FUNC&&) { + return r.val; +} + +int main(int, char**) { + const Wrapper w{1234}; + const auto& u = unwrap_2(w, 1L); // { dg-bogus "dangling reference" } + __builtin_printf("Unwrapped value : %d\n", u); +}