From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 9C7093858D37 for ; Tue, 1 Nov 2022 22:07:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9C7093858D37 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1667340425; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=uBwVtINrKm8b0mlfFPuU1wlCdDhPHr3MOTWrPpbz25Q=; b=bVqCkjCiOBlO5YCrCqVZmFrKPmDkGP9ZRp72o4P+JRGEO9bWKA5RFCSOrd44HihxEZdEQx j459BFAT/tkgDO5v8JtKqfO3IKJTUx6X+BTgdVcLUtrpMAGMrZ12j/SJJ6bd3W5XS0R4gH yGGx7EUlc6W6UFIaW0wAVMnKKJKqvLA= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-375-e0TfHcSWMs6ToMpY1W-qHg-1; Tue, 01 Nov 2022 18:07:02 -0400 X-MC-Unique: e0TfHcSWMs6ToMpY1W-qHg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 5F056381078E for ; Tue, 1 Nov 2022 22:07:02 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.16.170]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3B4CD1415121; Tue, 1 Nov 2022 22:07:02 +0000 (UTC) From: Marek Polacek To: Jason Merrill , GCC Patches Subject: [PATCH] c++: Quash -Wdangling-reference for member operator* [PR107488] Date: Tue, 1 Nov 2022 18:06:52 -0400 Message-Id: <20221101220652.588178-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-13.0 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_H2,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 List-Id: -Wdangling-reference complains here: std::vector v = ...; std::vector::const_iterator it = v.begin(); while (it != v.end()) { const int &r = *it++; // warning } because it sees a call to __gnu_cxx::__normal_iterator >::operator* which returns a reference and its argument is a TARGET_EXPR representing the result of __gnu_cxx::__normal_iterator >::operator++ But 'r' above refers to one of the int elements of the vector 'v', not to a temporary object. Therefore the warning is a false positive. I suppose code like the above is relatively common (the warning broke cppunit-1.15.1 and a few other projects), so presumably it makes sense to suppress the warning when it comes to member operator*. In this case it's defined as reference operator*() const _GLIBCXX_NOEXCEPT { return *_M_current; } and I'm guessing a lot of member operator* are like that, at least when it comes to iterators. I've looked at _Fwd_list_iterator, _Fwd_list_const_iterator, __shared_ptr_access, _Deque_iterator, istream_iterator, etc, and they're all like that, so adding #pragmas would be quite tedious. :/ Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? PR c++/107488 gcc/cp/ChangeLog: * call.cc (do_warn_dangling_reference): Quash -Wdangling-reference for member operator*. gcc/testsuite/ChangeLog: * g++.dg/warn/Wdangling-reference5.C: New test. --- gcc/cp/call.cc | 12 +++++++++- .../g++.dg/warn/Wdangling-reference5.C | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-reference5.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index c7c7a122045..2c0fa37f53a 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -13467,7 +13467,17 @@ do_warn_dangling_reference (tree expr) can be e.g. const int& z = std::min({1, 2, 3, 4, 5, 6, 7}); which doesn't dangle: std::min here returns an int. */ - || !TYPE_REF_OBJ_P (TREE_TYPE (TREE_TYPE (fndecl)))) + || !TYPE_REF_OBJ_P (TREE_TYPE (TREE_TYPE (fndecl))) + /* Don't emit a false positive for: + std::vector v = ...; + std::vector::const_iterator it = v.begin(); + const int &r = *it++; + because R refers to one of the int elements of V, not to + a temporary object. Member operator* may return a reference + but probably not to one of its arguments. */ + || (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl) + && DECL_OVERLOADED_OPERATOR_P (fndecl) + && DECL_OVERLOADED_OPERATOR_IS (fndecl, INDIRECT_REF))) return NULL_TREE; /* Here we're looking to see if any of the arguments is a temporary diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference5.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference5.C new file mode 100644 index 00000000000..59b5538aee5 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference5.C @@ -0,0 +1,22 @@ +// PR c++/107488 +// { dg-do compile } +// { dg-options "-Wdangling-reference" } + +#include + +int +do_sum (std::vector& v) +{ + int sum = 0; + + std::vector::const_iterator it = v.begin(); + while (it != v.end()) + { + // R refers to one of the int elements of V, not to a temporary + // object, so no dangling reference here. + const int &r = *it++; // { dg-bogus "dangling reference" } + sum += r; + } + + return sum; +} base-commit: 2b0e81d5cc2f7e1d773f6c502bd65b097f392675 -- 2.38.1