public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Marek Polacek <mpolacek@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-8375] c++: -Wdangling-reference and lambda false warning [PR109640] Date: Tue, 23 Jan 2024 21:36:03 +0000 (GMT) [thread overview] Message-ID: <20240123213603.55D8E3858420@sourceware.org> (raw) https://gcc.gnu.org/g:9010fdba68063beccfbab0aa9ec8739f232ca2f4 commit r14-8375-g9010fdba68063beccfbab0aa9ec8739f232ca2f4 Author: Marek Polacek <polacek@redhat.com> Date: Fri Jan 19 13:59:41 2024 -0500 c++: -Wdangling-reference and lambda false warning [PR109640] -Wdangling-reference checks if a function receives a temporary as its argument, and only warns if any of the arguments was a temporary. But we should not warn when the temporary represents a lambda or we generate false positives as in the attached testcases. PR c++/113256 PR c++/111607 PR c++/109640 gcc/cp/ChangeLog: * call.cc (do_warn_dangling_reference): Don't warn if the temporary is of lambda type. gcc/testsuite/ChangeLog: * g++.dg/warn/Wdangling-reference14.C: New test. * g++.dg/warn/Wdangling-reference15.C: New test. * g++.dg/warn/Wdangling-reference16.C: New test. Diff: --- gcc/cp/call.cc | 9 ++++--- gcc/testsuite/g++.dg/warn/Wdangling-reference14.C | 22 ++++++++++++++++ gcc/testsuite/g++.dg/warn/Wdangling-reference15.C | 31 +++++++++++++++++++++++ gcc/testsuite/g++.dg/warn/Wdangling-reference16.C | 13 ++++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 1f5ff417c81..77f51bacce3 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -14123,7 +14123,10 @@ do_warn_dangling_reference (tree expr, bool arg_p) tree e = expr; while (handled_component_p (e)) e = TREE_OPERAND (e, 0); - if (!reference_like_class_p (TREE_TYPE (e))) + tree type = TREE_TYPE (e); + /* If the temporary represents a lambda, we don't really know + what's going on here. */ + if (!reference_like_class_p (type) && !LAMBDA_TYPE_P (type)) return expr; } @@ -14180,10 +14183,10 @@ do_warn_dangling_reference (tree expr, bool arg_p) initializing this reference parameter. */ if (do_warn_dangling_reference (arg, /*arg_p=*/true)) return expr; - /* Don't warn about member function like: + /* Don't warn about member functions like: std::any a(...); S& s = a.emplace<S>({0}, 0); - which constructs a new object and returns a reference to it, but + which construct a new object and return a reference to it, but we still want to detect: struct S { const S& self () { return *this; } }; const S& s = S().self(); diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference14.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference14.C new file mode 100644 index 00000000000..92b38a965e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference14.C @@ -0,0 +1,22 @@ +// PR c++/113256 +// { dg-do compile { target c++14 } } +// { dg-options "-Wdangling-reference" } + +#include <utility> +#include <cassert> + +template<class M, class T, class A> auto bind(M T::* pm, A) +{ + return [=]( auto&& x ) -> M const& { return x.*pm; }; +} + +template<int I> struct arg {}; + +arg<1> _1; + +int main() +{ + std::pair<int, int> pair; + int const& x = bind( &std::pair<int, int>::first, _1 )( pair ); // { dg-bogus "dangling reference" } + assert( &x == &pair.first ); +} diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference15.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference15.C new file mode 100644 index 00000000000..c39577db64a --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference15.C @@ -0,0 +1,31 @@ +// PR c++/111607 +// { dg-do compile { target c++20 } } +// { dg-options "-Wdangling-reference" } + +#include <variant> + +struct S { + constexpr S(int i_) : i(i_) {} + S(S const &) = delete; + S & operator=(S const &) = delete; + S(S &&) = delete; + S & operator=(S &&) = delete; + int i; +}; + +struct A { + S s{0}; +}; + +using V = std::variant<A>; + +consteval auto f(V const & v) { + auto const & s = std::visit([](auto const & v) -> S const & { return v.s; }, v); // { dg-bogus "dangling reference" } + return s.i; +} + +int main() { + constexpr V a{std::in_place_type<A>}; + constexpr auto i = f(a); + return i; +} diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference16.C b/gcc/testsuite/g++.dg/warn/Wdangling-reference16.C new file mode 100644 index 00000000000..91996922291 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference16.C @@ -0,0 +1,13 @@ +// PR c++/109640 +// { dg-do compile { target c++11 } } +// { dg-options "-Wdangling-reference" } + +bool +fn0 () +{ + int a; + int&& i = [](int& r) -> int&& { return static_cast<int&&>(r); }(a); // { dg-bogus "dangling reference" } + auto const l = [](int& r) -> int&& { return static_cast<int&&>(r); }; + int&& j = l(a); + return &i == &j; +}
reply other threads:[~2024-01-23 21:36 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240123213603.55D8E3858420@sourceware.org \ --to=mpolacek@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).