On Tue, Sep 17, 2024 at 05:16:48PM -0400, Jason Merrill wrote: > Tested x86_64-pc-linux-gnu. Marek, thoughts?
Makes sense. OK, thanks. > -- 8< -- > > The -Wdangling-reference diagnostic talks about the full-expression, but > prints one call, while the full-expression in a declaration is the entire > initialization. It seems more useful to point out the temporary that the > compiler thinks we might be getting a dangling reference to. > > gcc/cp/ChangeLog: > > * call.cc (do_warn_dangling_reference): Return temporary > instead of the call it's passed to. > (maybe_warn_dangling_reference): Adjust diagnostic. > > gcc/testsuite/ChangeLog: > > * g++.dg/warn/Wdangling-reference1.C: Adjust diagnostic. > --- > gcc/cp/call.cc | 23 +++++++++---------- > .../g++.dg/warn/Wdangling-reference1.C | 2 +- > 2 files changed, 12 insertions(+), 13 deletions(-) > > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc > index 1ecf3aac705..3f753e2d2f9 100644 > --- a/gcc/cp/call.cc > +++ b/gcc/cp/call.cc > @@ -14253,19 +14253,18 @@ reference_like_class_p (tree ctype) > return false; > } > > -/* Helper for maybe_warn_dangling_reference to find a problematic CALL_EXPR > - that initializes the LHS (and at least one of its arguments represents > - a temporary, as outlined in maybe_warn_dangling_reference), or NULL_TREE > +/* Helper for maybe_warn_dangling_reference to find a problematic temporary > + in EXPR (as outlined in maybe_warn_dangling_reference), or NULL_TREE > if none found. For instance: > > - const S& s = S().self(); // S::self (&TARGET_EXPR <...>) > - const int& r = (42, f(1)); // f(1) > - const int& t = b ? f(1) : f(2); // f(1) > - const int& u = b ? f(1) : f(g); // f(1) > - const int& v = b ? f(g) : f(2); // f(2) > + const S& s = S().self(); // S() > + const int& r = (42, f(1)); // temporary for passing 1 to f > + const int& t = b ? f(1) : f(2); // temporary for 1 > + const int& u = b ? f(1) : f(g); // temporary for 1 > + const int& v = b ? f(g) : f(2); // temporary for 2 > const int& w = b ? f(g) : f(g); // NULL_TREE > const int& y = (f(1), 42); // NULL_TREE > - const int& z = f(f(1)); // f(f(1)) > + const int& z = f(f(1)); // temporary for 1 > > EXPR is the initializer. If ARG_P is true, we're processing an argument > to a function; the point is to distinguish between, for example, > @@ -14365,7 +14364,7 @@ do_warn_dangling_reference (tree expr, bool arg_p) > && !reference_related_p (TREE_TYPE (rettype), > TREE_TYPE (arg))) > continue; > - return expr; > + return arg; > } > /* Don't warn about member functions like: > std::any a(...); > @@ -14438,8 +14437,8 @@ maybe_warn_dangling_reference (const_tree decl, tree > init) > auto_diagnostic_group d; > if (warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wdangling_reference, > "possibly dangling reference to a temporary")) > - inform (EXPR_LOCATION (call), "the temporary was destroyed at " > - "the end of the full expression %qE", call); > + inform (EXPR_LOCATION (call), "%qT temporary created here", > + TREE_TYPE (call)); > } > } > > diff --git a/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C > b/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C > index a184317dd5c..5e60a415836 100644 > --- a/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C > +++ b/gcc/testsuite/g++.dg/warn/Wdangling-reference1.C > @@ -117,7 +117,7 @@ const B& b10 = lox (H{}); // { dg-warning "dangling > reference" } > > struct S { > const int &r; // { dg-warning "dangling reference" } > - S() : r(f(10)) { } // { dg-message "destroyed" } > + S() : r(f(10)) { } // { dg-message "created" } > }; > > // From cppreference. > -- > 2.46.0 > Marek