Author: NeKon69 Date: 2026-05-27T08:05:48+02:00 New Revision: a3adb545b6a33044ab634b7a330bab5d4ee76d24
URL: https://github.com/llvm/llvm-project/commit/a3adb545b6a33044ab634b7a330bab5d4ee76d24 DIFF: https://github.com/llvm/llvm-project/commit/a3adb545b6a33044ab634b7a330bab5d4ee76d24.diff LOG: [LifetimeSafety] Add details for `-Wlifetime-safety-return-stack-addr` diagnostic (#199432) Most of the diagnostic's wording was taken from `-Wreturn-stack-address` with exceptions such as: - We do not special-case `[[clang::musttail]]` - We do not special-case `CompoundLiteralExpr` as it is mostly a C thing. This patch does not add any new tests, it only updates already existing test warnings to follow the new wording. Comes as part of completing #186002 Added: Modified: clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Analysis/LifetimeSafety/Checker.cpp clang/lib/Sema/SemaLifetimeSafety.h clang/test/Sema/warn-lifetime-analysis-nocfg.cpp clang/test/Sema/warn-lifetime-safety-suggestions.cpp clang/test/Sema/warn-lifetime-safety.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h index ec9f83748ad8d..398cce1395854 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h @@ -67,8 +67,7 @@ class LifetimeSafetySemaHelper { virtual void reportUseAfterReturn(const Expr *IssueExpr, const Expr *ReturnExpr, - const Expr *MovedExpr, - SourceLocation ExpiryLoc) {} + const Expr *MovedExpr) {} virtual void reportDanglingField(const Expr *IssueExpr, const FieldDecl *Field, diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6db3ba738cd10..5856a02bfbda1 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10970,16 +10970,15 @@ def warn_lifetime_safety_use_after_free : Warning< "%select{allocated object|parameter}0 does not live long enough">, InGroup<LifetimeSafetyUseAfterFree>, DefaultIgnore; -def warn_lifetime_safety_return_stack_addr - : Warning<"address of stack memory is returned later">, - InGroup<LifetimeSafetyReturnStackAddr>, - DefaultIgnore; -def warn_lifetime_safety_return_stack_addr_moved - : Warning<"address of stack memory may be returned later. " - "This could be false positive as the storage may have been moved. " - "Consider moving first and then aliasing later to resolve the issue">, - InGroup<LifetimeSafetyReturnStackAddrMoved>, - DefaultIgnore; +def warn_lifetime_safety_return_stack_addr : Warning< + "stack memory associated with %0 is returned">, + InGroup<LifetimeSafetyReturnStackAddr>, DefaultIgnore; + +def warn_lifetime_safety_return_stack_addr_moved : Warning< + "stack memory associated with %0 may be returned later. " + "This could be a false positive as the storage may have been moved. " + "Consider moving first and then aliasing later to resolve the issue">, + InGroup<LifetimeSafetyReturnStackAddrMoved>, DefaultIgnore; def warn_lifetime_safety_invalidation : Warning<"%select{object whose reference is captured|parameter}0 is later invalidated">, diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp index 7eb948373152b..d6d4ec6b5617e 100644 --- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp +++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp @@ -300,7 +300,7 @@ class LifetimeChecker { } else if (const auto *RetEscape = dyn_cast<ReturnEscapeFact>(OEF)) // Return stack address. SemaHelper->reportUseAfterReturn( - IssueExpr, RetEscape->getReturnExpr(), MovedExpr, ExpiryLoc); + IssueExpr, RetEscape->getReturnExpr(), MovedExpr); else if (const auto *FieldEscape = dyn_cast<FieldEscapeFact>(OEF)) // Dangling field. SemaHelper->reportDanglingField( diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h index af5202c33fed0..0305510c1a233 100644 --- a/clang/lib/Sema/SemaLifetimeSafety.h +++ b/clang/lib/Sema/SemaLifetimeSafety.h @@ -20,6 +20,7 @@ #include "clang/Basic/DiagnosticSema.h" #include "clang/Lex/Lexer.h" #include "clang/Sema/Sema.h" +#include <string> namespace clang::lifetimes { @@ -75,12 +76,14 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper { } void reportUseAfterReturn(const Expr *IssueExpr, const Expr *ReturnExpr, - const Expr *MovedExpr, - SourceLocation ExpiryLoc) override { - S.Diag(IssueExpr->getExprLoc(), - MovedExpr ? diag::warn_lifetime_safety_return_stack_addr_moved - : diag::warn_lifetime_safety_return_stack_addr) - << IssueExpr->getSourceRange(); + const Expr *MovedExpr) override { + unsigned DiagID = MovedExpr + ? diag::warn_lifetime_safety_return_stack_addr_moved + : diag::warn_lifetime_safety_return_stack_addr; + + S.Diag(IssueExpr->getExprLoc(), DiagID) + << getDiagSubjectDescription(IssueExpr) << IssueExpr->getSourceRange(); + if (MovedExpr) S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here) << MovedExpr->getSourceRange(); @@ -396,6 +399,26 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper { } private: + std::string getDiagSubjectDescription(const ValueDecl *VD) { + std::string Res; + llvm::raw_string_ostream OS(Res); + OS << (isa<ParmVarDecl>(VD) ? "parameter" : "local variable"); + OS << " '"; + VD->getNameForDiagnostic(OS, S.getPrintingPolicy(), /*Qualified=*/false); + OS << "'"; + return Res; + } + + std::string getDiagSubjectDescription(const Expr *E) { + if (isa<MaterializeTemporaryExpr>(E)) + return "local temporary object"; + + if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) + return getDiagSubjectDescription(DRE->getDecl()); + // TODO: Handle other expression types. + return ""; + } + Sema &S; }; diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index 00d45caae3b09..9c53129ff707d 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -98,7 +98,7 @@ struct DanglingGslPtrField { MyIntPointer danglingGslPtrFromLocal() { int j; // Detected only by CFG analysis. - return &j; // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + return &j; // cfg-warning {{stack memory associated with local variable 'j' is returned}} cfg-note {{returned here}} } MyIntPointer returningLocalPointer() { @@ -109,30 +109,30 @@ MyIntPointer returningLocalPointer() { MyIntPointer daglingGslPtrFromLocalOwner() { MyIntOwner localOwner; return localOwner; // expected-warning {{address of stack memory associated with local variable 'localOwner' returned}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'localOwner' is returned}} cfg-note {{returned here}} } MyLongPointerFromConversion daglingGslPtrFromLocalOwnerConv() { MyLongOwnerWithConversion localOwner; return localOwner; // expected-warning {{address of stack memory associated with local variable 'localOwner' returned}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'localOwner' is returned}} cfg-note {{returned here}} } MyIntPointer danglingGslPtrFromTemporary() { return MyIntOwner{}; // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } MyIntOwner makeTempOwner(); MyIntPointer danglingGslPtrFromTemporary2() { return makeTempOwner(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } MyLongPointerFromConversion danglingGslPtrFromTemporaryConv() { return MyLongOwnerWithConversion{}; // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } int *noFalsePositive(MyIntOwner &o) { @@ -180,7 +180,7 @@ struct LifetimeBoundCtor { }; auto lifetimebound_make_unique_single_param() { - return std::make_unique<LifetimeBoundCtor>(MyIntOwner{}); // tu-warning {{address of stack memory is returned later}} tu-note {{returned here}} + return std::make_unique<LifetimeBoundCtor>(MyIntOwner{}); // tu-warning {{stack memory associated with local temporary object is returned}} tu-note {{returned here}} } @@ -199,17 +199,17 @@ void modelIterators() { std::vector<int>::iterator modelIteratorReturn() { return std::vector<int>().begin(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } const int *modelFreeFunctions() { return std::data(std::vector<int>()); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } int &modelAnyCast() { return std::any_cast<int&>(std::any{}); // expected-warning {{returning reference to local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } int modelAnyCast2() { @@ -223,19 +223,19 @@ int modelAnyCast3() { const char *danglingRawPtrFromLocal() { std::basic_string<char> s; return s.c_str(); // expected-warning {{address of stack memory associated with local variable 's' returned}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 's' is returned}} cfg-note {{returned here}} } int &danglingRawPtrFromLocal2() { std::optional<int> o; return o.value(); // expected-warning {{reference to stack memory associated with local variable 'o' returned}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'o' is returned}} cfg-note {{returned here}} } int &danglingRawPtrFromLocal3() { std::optional<int> o; return *o; // expected-warning {{reference to stack memory associated with local variable 'o' returned}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'o' is returned}} cfg-note {{returned here}} } // GH100384 @@ -254,14 +254,14 @@ std::string_view containerWithAnnotatedElements() { std::vector<std::string> local; return local.at(0); // expected-warning {{address of stack memory associated with local variable}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'local' is returned}} cfg-note {{returned here}} } std::string_view localUniquePtr(int i) { std::unique_ptr<std::string> c1; if (i) return *c1; // expected-warning {{address of stack memory associated with local variable}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'c1' is returned}} cfg-note {{returned here}} std::unique_ptr<std::string_view> c2; return *c2; // expect no-warning. } @@ -270,38 +270,38 @@ std::string_view localOptional(int i) { std::optional<std::string> o; if (i) return o.value(); // expected-warning {{address of stack memory associated with local variable}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'o' is returned}} cfg-note {{returned here}} std::optional<std::string_view> abc; return abc.value(); // expect no warning } const char *danglingRawPtrFromTemp() { return std::basic_string<char>().c_str(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } std::unique_ptr<int> getUniquePtr(); int *danglingUniquePtrFromTemp() { return getUniquePtr().get(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } int *danglingUniquePtrFromTemp2() { return std::unique_ptr<int>().get(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } const int& danglingRefToOptionalFromTemp3() { return std::optional<int>().value(); // expected-warning {{returning reference to local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } std::optional<std::string> getTempOptStr(); std::string_view danglingRefToOptionalFromTemp4() { return getTempOptStr().value(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } void danglingReferenceFromTempOwner() { @@ -346,14 +346,14 @@ int &usedToBeFalsePositive(std::vector<int> &v) { int &doNotFollowReferencesForLocalOwner() { // Warning caught by CFG analysis. std::unique_ptr<int> localOwner; - int &p = *localOwner // cfg-warning {{address of stack memory is returned later}} + int &p = *localOwner // cfg-warning {{stack memory associated with local variable 'localOwner' is returned}} .get(); return p; // cfg-note {{returned here}} } const char *trackThroughMultiplePointer() { return std::basic_string_view<char>(std::basic_string<char>()).begin(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } struct X { @@ -447,11 +447,11 @@ std::vector<std::string_view> GetTemporaryView(); std::string_view test_str_local() { std::vector<std::string> v; - return *std::find(v.begin(), // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + return *std::find(v.begin(), // cfg-warning {{stack memory associated with local variable 'v' is returned}} cfg-note {{returned here}} v.end(), "42"); } std::string_view test_str_temporary() { - return *std::find(GetTemporaryString().begin(), // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + return *std::find(GetTemporaryString().begin(), // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} GetTemporaryString().end(), "42"); } std::string_view test_view() { @@ -566,7 +566,7 @@ struct [[gsl::Pointer]] S { S test(std::vector<int> a) { return S(a); // expected-warning {{address of stack memory associated with}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with parameter 'a' is returned}} cfg-note {{returned here}} } // FIXME: Detect this using the CFG-based lifetime analysis (global initialisation). @@ -586,10 +586,10 @@ struct FooView { FooView test3(int i, std::optional<Foo> a) { if (i) return *a; // expected-warning {{address of stack memory}} \ - // cfg-warning {{address of stack memory is returned later}} \ + // cfg-warning {{stack memory associated with parameter 'a' is returned}} \ // cfg-note {{returned here}} return a.value(); // expected-warning {{address of stack memory}} \ - // cfg-warning {{address of stack memory is returned later}} \ + // cfg-warning {{stack memory associated with parameter 'a' is returned}} \ // cfg-note {{returned here}} } } // namespace GH93386 @@ -649,7 +649,7 @@ std::string_view test2() { std::string_view bad = StatusOr<Wrapper2<std::string_view>>().value(); // expected-warning {{temporary whose address is used as value of}} return k.value(); // expected-warning {{address of stack memory associated}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 'k' is returned}} cfg-note {{returned here}} } } // namespace GH108272 @@ -781,7 +781,7 @@ Span<int*> test6(std::vector<int*> v) { Span<int *> dangling = std::vector<int*>(); // expected-warning {{object backing the pointer}} dangling = std::vector<int*>(); // expected-warning {{object backing the pointer}} return v; // expected-warning {{address of stack memory}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with parameter 'v' is returned}} cfg-note {{returned here}} } /////// From Owner<Owner<Pointer>> /////// @@ -801,7 +801,7 @@ std::vector<int*> test8(StatusOr<std::vector<int*>> aa) { // Pointer<Pointer> from Owner<Owner<Pointer>> Span<int*> test9(StatusOr<std::vector<int*>> aa) { return aa.valueLB(); // expected-warning {{address of stack memory associated}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with parameter 'aa' is returned}} cfg-note {{returned here}} return aa.valueNoLB(); // OK. } @@ -810,7 +810,7 @@ Span<int*> test9(StatusOr<std::vector<int*>> aa) { // Pointer<Owner>> from Owner<Owner> Span<std::string> test10(StatusOr<std::vector<std::string>> aa) { return aa.valueLB(); // expected-warning {{address of stack memory}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with parameter 'aa' is returned}} cfg-note {{returned here}} return aa.valueNoLB(); // OK. } @@ -825,7 +825,7 @@ Span<std::string> test11(StatusOr<Span<std::string>> aa) { // Lifetimebound and gsl::Pointer. const int& test12(Span<int> a) { return a.getFieldLB(); // expected-warning {{reference to stack memory associated}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with parameter 'a' is returned}} cfg-note {{returned here}} return a.getFieldNoLB(); // OK. } @@ -865,7 +865,7 @@ std::string_view test1_1() { // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} use(t1); // cfg-note {{later used here}} return Ref(std::string()); // expected-warning {{returning address}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } std::string_view test1_2() { @@ -877,7 +877,7 @@ std::string_view test1_2() { use(t2); // cfg-note {{later used here}} return TakeSv(std::string()); // expected-warning {{returning address}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } std::string_view test1_3() { @@ -888,7 +888,7 @@ std::string_view test1_3() { // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} use(t3); // cfg-note {{later used here}} return TakeStrRef(std::string()); // expected-warning {{returning address}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} } std::string_view test1_4() { @@ -913,7 +913,7 @@ std::string_view test2_1(Foo<std::string> r1, Foo<std::string_view> r2) { // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} use(t1); // cfg-note {{later used here}} return r1.get(); // expected-warning {{address of stack}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with parameter 'r1' is returned}} cfg-note {{returned here}} } std::string_view test2_2(Foo<std::string> r1, Foo<std::string_view> r2) { std::string_view t2 = Foo<std::string_view>().get(); @@ -943,7 +943,7 @@ Pointer test3(Bar bar) { use(p); // cfg-note {{later used here}} p = Pointer(Bar()); // expected-warning {{object backing}} cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} use(p); // cfg-note {{later used here}} - return bar; // expected-warning {{address of stack}} cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + return bar; // expected-warning {{address of stack}} cfg-warning {{stack memory associated with parameter 'bar' is returned}} cfg-note {{returned here}} } template<typename T> @@ -980,14 +980,14 @@ void test4() { namespace range_based_for_loop_variables { std::string_view test_view_loop_var(std::vector<std::string> strings) { - for (std::string_view s : strings) { // cfg-warning {{address of stack memory is returned later}} + for (std::string_view s : strings) { // cfg-warning {{stack memory associated with parameter 'strings' is returned}} return s; //cfg-note {{returned here}} } return ""; } const char* test_view_loop_var_with_data(std::vector<std::string> strings) { - for (std::string_view s : strings) { // cfg-warning {{address of stack memory is returned later}} + for (std::string_view s : strings) { // cfg-warning {{stack memory associated with parameter 'strings' is returned}} return s.data(); //cfg-note {{returned here}} } return ""; @@ -1001,14 +1001,14 @@ std::string_view test_no_error_for_views(std::vector<std::string_view> views) { } std::string_view test_string_ref_var(std::vector<std::string> strings) { - for (const std::string& s : strings) { // cfg-warning {{address of stack memory is returned later}} + for (const std::string& s : strings) { // cfg-warning {{stack memory associated with parameter 'strings' is returned}} return s; //cfg-note {{returned here}} } return ""; } std::string_view test_opt_strings(std::optional<std::vector<std::string>> strings_or) { - for (const std::string& s : *strings_or) { // cfg-warning {{address of stack memory is returned later}} + for (const std::string& s : *strings_or) { // cfg-warning {{stack memory associated with parameter 'strings_or' is returned}} return s; //cfg-note {{returned here}} } return ""; @@ -1018,7 +1018,7 @@ std::string_view test_opt_strings(std::optional<std::vector<std::string>> string namespace iterator_arrow { std::string_view test() { std::vector<std::string> strings; - return strings.begin()->data(); // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + return strings.begin()->data(); // cfg-warning {{stack memory associated with local variable 'strings' is returned}} cfg-note {{returned here}} } void operator_star_arrow_reference() { @@ -1143,7 +1143,7 @@ struct StatusOr { const char* foo() { StatusOr<std::string> s; return s->data(); // expected-warning {{address of stack memory associated with local variable}} \ - // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with local variable 's' is returned}} cfg-note {{returned here}} StatusOr<std::string_view> s2; return s2->data(); diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp index d9aa308986913..24aacc9480533 100644 --- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp +++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp @@ -371,7 +371,7 @@ View inference_caller_forwards_callee(View a) { // expected-warning {{parameter View inference_top_level_return_stack_view() { MyObj local_stack; - return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}} + return inference_caller_forwards_callee(local_stack); // expected-warning {{stack memory associated with local variable 'local_stack' is returned}} // expected-note@-1 {{returned here}} } } // namespace simple_annotation_inference @@ -389,7 +389,7 @@ View inference_caller_forwards_callee(View a) { View inference_top_level_return_stack_view() { MyObj local_stack; - return inference_caller_forwards_callee(local_stack); // expected-warning {{address of stack memory is returned later}} + return inference_caller_forwards_callee(local_stack); // expected-warning {{stack memory associated with local variable 'local_stack' is returned}} // expected-note@-1 {{returned here}} } } // namespace inference_in_order_with_redecls @@ -407,7 +407,7 @@ T* template_caller(T* a) { // expected-warning {{parameter in intra MyObj* test_template_inference_with_stack() { MyObj local_stack; - return template_caller(&local_stack); // expected-warning {{address of stack memory is returned later}} + return template_caller(&local_stack); // expected-warning {{stack memory associated with local variable 'local_stack' is returned}} // expected-note@-1 {{returned here}} } } // namespace inference_with_templates @@ -468,7 +468,9 @@ void Foo(int, int*, const MyObj&, View); auto implicit_ref_capture(int integer, int* ptr, const MyObj& ref, // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}} View view) { - return [&]() { Foo(integer, ptr, ref, view); }; // expected-warning 3 {{address of stack memory is returned later}} \ + return [&]() { Foo(integer, ptr, ref, view); }; // expected-warning {{stack memory associated with parameter 'ptr' is returned}} \ + // expected-warning {{stack memory associated with parameter 'view' is returned}} \ + // expected-warning {{stack memory associated with parameter 'integer' is returned}} \ // expected-note 3 {{returned here}} \ // expected-note {{param returned here}} } @@ -522,7 +524,7 @@ struct CaptureRefToView { CaptureRefToView test_ref_to_view() { MyObj obj; - CaptureRefToView x(obj); // expected-warning {{address of stack memory is returned later}} + CaptureRefToView x(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} return x; // expected-note {{returned here}} } @@ -533,7 +535,7 @@ struct CaptureRefToPtr { CaptureRefToPtr test_ref_to_ptr() { MyObj obj; - CaptureRefToPtr x(obj); // expected-warning {{address of stack memory is returned later}} + CaptureRefToPtr x(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} return x; // expected-note {{returned here}} } @@ -544,7 +546,7 @@ struct CaptureViewToView { CaptureViewToView test_view_to_view() { MyObj obj; - View v(obj); // expected-warning {{address of stack memory is returned later}} + View v(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} CaptureViewToView x(v); return x; // expected-note {{returned here}} } @@ -556,7 +558,7 @@ struct CapturePtrToPtr { CapturePtrToPtr test_ptr_to_ptr() { MyObj obj; - CapturePtrToPtr x(&obj); // expected-warning {{address of stack memory is returned later}} + CapturePtrToPtr x(&obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} return x; // expected-note {{returned here}} } @@ -567,7 +569,7 @@ struct CaptureRefToRef { CaptureRefToRef test_ref_to_ref() { MyObj obj; - CaptureRefToRef x(obj); // expected-warning {{address of stack memory is returned later}} + CaptureRefToRef x(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} return x; // expected-note {{returned here}} } @@ -582,7 +584,7 @@ struct CaptureRefToBaseView : BaseWithView { CaptureRefToBaseView test_ref_to_base_view() { MyObj obj; - CaptureRefToBaseView x(obj); // expected-warning {{address of stack memory is returned later}} + CaptureRefToBaseView x(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} return x; // expected-note {{returned here}} } } // namespace capturing_constructor @@ -651,7 +653,7 @@ struct HasCtorField { HasCtorField test_dangling_field_ctor() { MyObj obj; - HasCtorField x(obj); // expected-warning {{address of stack memory is returned later}} + HasCtorField x(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} return x; // expected-note {{returned here}} } diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp index 0619fda738fa4..bd61acdb8d8cb 100644 --- a/clang/test/Sema/warn-lifetime-safety.cpp +++ b/clang/test/Sema/warn-lifetime-safety.cpp @@ -488,13 +488,13 @@ void small_scope_reference_var_no_error() { MyObj* simple_return_stack_address() { MyObj s; - MyObj* p = &s; // expected-warning {{address of stack memory is returned later}} + MyObj* p = &s; // expected-warning {{stack memory associated with local variable 's' is returned}} return p; // expected-note {{returned here}} } MyObj* direct_return() { MyObj s; - return &s; // expected-warning {{address of stack memory is returned later}} + return &s; // expected-warning {{stack memory associated with local variable 's' is returned}} // expected-note@-1 {{returned here}} } @@ -517,7 +517,7 @@ const MyObj* conditional_assign_unconditional_return(const MyObj& safe, bool c) MyObj s; const MyObj* p = &safe; if (c) { - p = &s; // expected-warning {{address of stack memory is returned later}} + p = &s; // expected-warning {{stack memory associated with local variable 's' is returned}} } return p; // expected-note {{returned here}} } @@ -526,7 +526,7 @@ View conditional_assign_both_branches(const MyObj& safe, bool c) { MyObj s; View p; if (c) { - p = s; // expected-warning {{address of stack memory is returned later}} + p = s; // expected-warning {{stack memory associated with local variable 's' is returned}} } else { p = safe; @@ -538,13 +538,13 @@ View conditional_assign_both_branches(const MyObj& safe, bool c) { View reassign_safe_to_local(const MyObj& safe) { MyObj local; View p = safe; - p = local; // expected-warning {{address of stack memory is returned later}} + p = local; // expected-warning {{stack memory associated with local variable 'local' is returned}} return p; // expected-note {{returned here}} } View pointer_chain_to_local() { MyObj local; - View p1 = local; // expected-warning {{address of stack memory is returned later}} + View p1 = local; // expected-warning {{stack memory associated with local variable 'local' is returned}} View p2 = p1; return p2; // expected-note {{returned here}} } @@ -554,11 +554,11 @@ View multiple_assign_multiple_return(const MyObj& safe, bool c1, bool c2) { MyObj local2; View p; if (c1) { - p = local1; // expected-warning {{address of stack memory is returned later}} + p = local1; // expected-warning {{stack memory associated with local variable 'local1' is returned}} return p; // expected-note {{returned here}} } else if (c2) { - p = local2; // expected-warning {{address of stack memory is returned later}} + p = local2; // expected-warning {{stack memory associated with local variable 'local2' is returned}} return p; // expected-note {{returned here}} } p = safe; @@ -570,10 +570,10 @@ View multiple_assign_single_return(const MyObj& safe, bool c1, bool c2) { MyObj local2; View p; if (c1) { - p = local1; // expected-warning {{address of stack memory is returned later}} + p = local1; // expected-warning {{stack memory associated with local variable 'local1' is returned}} } else if (c2) { - p = local2; // expected-warning {{address of stack memory is returned later}} + p = local2; // expected-warning {{stack memory associated with local variable 'local2' is returned}} } else { p = safe; @@ -583,42 +583,42 @@ View multiple_assign_single_return(const MyObj& safe, bool c1, bool c2) { View direct_return_of_local() { MyObj stack; - return stack; // expected-warning {{address of stack memory is returned later}} + return stack; // expected-warning {{stack memory associated with local variable 'stack' is returned}} // expected-note@-1 {{returned here}} } MyObj& reference_return_of_local() { MyObj stack; - return stack; // expected-warning {{address of stack memory is returned later}} + return stack; // expected-warning {{stack memory associated with local variable 'stack' is returned}} // expected-note@-1 {{returned here}} } int* trivial_int_uar() { int *a; int b = 1; - a = &b; // expected-warning {{address of stack memory is returned later}} + a = &b; // expected-warning {{stack memory associated with local variable 'b' is returned}} return a; // expected-note {{returned here}} } TriviallyDestructedClass* trivial_class_uar () { TriviallyDestructedClass *ptr; TriviallyDestructedClass s; - ptr = &s; // expected-warning {{address of stack memory is returned later}} + ptr = &s; // expected-warning {{stack memory associated with local variable 's' is returned}} return ptr; // expected-note {{returned here}} } const int& return_parameter(int a) { - return a; // expected-warning {{address of stack memory is returned later}} + return a; // expected-warning {{stack memory associated with parameter 'a' is returned}} // expected-note@-1 {{returned here}} } int* return_pointer_to_parameter(int a) { - return &a; // expected-warning {{address of stack memory is returned later}} + return &a; // expected-warning {{stack memory associated with parameter 'a' is returned}} // expected-note@-1 {{returned here}} } const int& return_reference_to_parameter(int a) { - const int &b = a; // expected-warning {{address of stack memory is returned later}} + const int &b = a; // expected-warning {{stack memory associated with parameter 'a' is returned}} return b; // expected-note {{returned here}} } int return_reference_to_parameter_no_error(int a) { @@ -628,30 +628,30 @@ int return_reference_to_parameter_no_error(int a) { MyObj*& return_ref_to_local_ptr_pointing_to_local() { MyObj local; - MyObj* p = &local; // expected-warning {{address of stack memory is returned later}} + MyObj* p = &local; // expected-warning {{stack memory associated with local variable 'local' is returned}} return p; // expected-note {{returned here}} \ - // expected-warning {{address of stack memory is returned later}} \ + // expected-warning {{stack memory associated with local variable 'p' is returned}} \ // expected-note {{returned here}} } const int& reference_via_conditional(int a, int b, bool cond) { - const int &c = (cond ? ((a)) : (b)); // expected-warning 2 {{address of stack memory is returned later}} + const int &c = (cond ? ((a)) : (b)); // expected-warning {{stack memory associated with parameter 'b' is returned}} expected-warning {{stack memory associated with parameter 'a' is returned}} return c; // expected-note 2 {{returned here}} } const int* return_pointer_to_parameter_via_reference(int a, int b, bool cond) { - const int &c = cond ? a : b; // expected-warning 2 {{address of stack memory is returned later}} + const int &c = cond ? a : b; // expected-warning {{stack memory associated with parameter 'b' is returned}} expected-warning {{stack memory associated with parameter 'a' is returned}} const int* d = &c; return d; // expected-note 2 {{returned here}} } const int& return_pointer_to_parameter_via_reference_1(int a) { - const int* d = &a; // expected-warning {{address of stack memory is returned later}} + const int* d = &a; // expected-warning {{stack memory associated with parameter 'a' is returned}} return *d; // expected-note {{returned here}} } const int& get_ref_to_local() { int a = 42; - return a; // expected-warning {{address of stack memory is returned later}} + return a; // expected-warning {{stack memory associated with local variable 'a' is returned}} // expected-note@-1 {{returned here}} } @@ -680,7 +680,7 @@ struct PtrHolder { int* const& test_ref_to_ptr() { PtrHolder a; - int *const &ref = a.getRef(); // expected-warning {{address of stack memory is returned later}} + int *const &ref = a.getRef(); // expected-warning {{stack memory associated with local variable 'a' is returned}} return ref; // expected-note {{returned here}} } int* const test_ref_to_ptr_no_error() { @@ -715,9 +715,9 @@ void test_assign_through_double_ptr() { int** test_ternary_double_ptr(bool cond) { int a = 1, b = 2; - int* pa = &a; // expected-warning {{address of stack memory is returned later}} - int* pb = &b; // expected-warning {{address of stack memory is returned later}} - int** result = cond ? &pa : &pb; // expected-warning 2 {{address of stack memory is returned later}} + int* pa = &a; // expected-warning {{stack memory associated with local variable 'a' is returned}} + int* pb = &b; // expected-warning {{stack memory associated with local variable 'b' is returned}} + int** result = cond ? &pa : &pb; // expected-warning {{stack memory associated with local variable 'pb' is returned}} expected-warning {{stack memory associated with local variable 'pa' is returned}} return result; // expected-note 4 {{returned here}} } //===----------------------------------------------------------------------===// @@ -738,7 +738,7 @@ View uar_before_uaf(const MyObj& safe, bool c) { View p; { MyObj local_obj; - p = local_obj; // expected-warning {{ddress of stack memory is returned later}} + p = local_obj; // expected-warning {{stack memory associated with local variable 'local_obj' is returned}} if (c) { return p; // expected-note {{returned here}} } @@ -1100,35 +1100,35 @@ void lifetimebound_make_unique_multi_params3_2() { View lifetimebound_return_of_local() { MyObj stack; - return Identity(stack); // expected-warning {{address of stack memory is returned later}} + return Identity(stack); // expected-warning {{stack memory associated with local variable 'stack' is returned}} // expected-note@-1 {{returned here}} } const MyObj& lifetimebound_return_ref_to_local() { MyObj stack; - return IdentityRef(stack); // expected-warning {{address of stack memory is returned later}} + return IdentityRef(stack); // expected-warning {{stack memory associated with local variable 'stack' is returned}} // expected-note@-1 {{returned here}} } View lifetimebound_return_by_value_param(MyObj stack_param) { - return Identity(stack_param); // expected-warning {{address of stack memory is returned later}} + return Identity(stack_param); // expected-warning {{stack memory associated with parameter 'stack_param' is returned}} // expected-note@-1 {{returned here}} } View lifetimebound_return_by_value_multiple_param(int cond, MyObj a, MyObj b, MyObj c) { if (cond == 1) - return Identity(a); // expected-warning {{address of stack memory is returned later}} + return Identity(a); // expected-warning {{stack memory associated with parameter 'a' is returned}} // expected-note@-1 {{returned here}} if (cond == 2) - return Identity(b); // expected-warning {{address of stack memory is returned later}} + return Identity(b); // expected-warning {{stack memory associated with parameter 'b' is returned}} // expected-note@-1 {{returned here}} - return Identity(c); // expected-warning {{address of stack memory is returned later}} + return Identity(c); // expected-warning {{stack memory associated with parameter 'c' is returned}} // expected-note@-1 {{returned here}} } template<class T> View lifetimebound_return_by_value_param_template(T t) { - return Identity(t); // expected-warning {{address of stack memory is returned later}} + return Identity(t); // expected-warning {{stack memory associated with parameter 't' is returned}} // expected-note@-1 {{returned here}} } void use_lifetimebound_return_by_value_param_template() { @@ -1137,7 +1137,7 @@ void use_lifetimebound_return_by_value_param_template() { void lambda_uar_param() { auto lambda = [](MyObj stack_param) { - return Identity(stack_param); // expected-warning {{address of stack memory is returned later}} + return Identity(stack_param); // expected-warning {{stack memory associated with parameter 'stack_param' is returned}} // expected-note@-1 {{returned here}} }; lambda(MyObj{}); @@ -1353,10 +1353,10 @@ void range_based_for_use_after_scope() { View range_based_for_use_after_return() { MyObjStorage s; - for (const MyObj &o : s) { // expected-warning {{address of stack memory is returned later}} + for (const MyObj &o : s) { // expected-warning {{stack memory associated with local variable 's' is returned}} return o; // expected-note {{returned here}} } - return *s.begin(); // expected-warning {{address of stack memory is returned later}} + return *s.begin(); // expected-warning {{stack memory associated with local variable 's' is returned}} // expected-note@-1 {{returned here}} } @@ -1406,7 +1406,7 @@ void test_user_defined_deref_uaf() { MyObj& test_user_defined_deref_uar() { MyObj obj; SmartPtr<MyObj> smart_ptr(&obj); - return *smart_ptr; // expected-warning {{address of stack memory is returned later}} + return *smart_ptr; // expected-warning {{stack memory associated with local variable 'smart_ptr' is returned}} // expected-note@-1 {{returned here}} } @@ -1469,29 +1469,29 @@ T&& MaxT(T&& a [[clang::lifetimebound]], T&& b [[clang::lifetimebound]]); const MyObj& call_max_with_obj() { MyObj oa, ob; - return MaxT(oa, // expected-warning {{address of stack memory is returned later}} + return MaxT(oa, // expected-warning {{stack memory associated with local variable 'oa' is returned}} // expected-note@-1 2 {{returned here}} - ob); // expected-warning {{address of stack memory is returned later}} + ob); // expected-warning {{stack memory associated with local variable 'ob' is returned}} } MyObj* call_max_with_obj_error() { MyObj oa, ob; - return &MaxT(oa, // expected-warning {{address of stack memory is returned later}} + return &MaxT(oa, // expected-warning {{stack memory associated with local variable 'oa' is returned}} // expected-note@-1 2 {{returned here}} - ob); // expected-warning {{address of stack memory is returned later}} + ob); // expected-warning {{stack memory associated with local variable 'ob' is returned}} } const MyObj* call_max_with_ref_obj_error() { MyObj oa, ob; - const MyObj& refa = oa; // expected-warning {{address of stack memory is returned later}} - const MyObj& refb = ob; // expected-warning {{address of stack memory is returned later}} + const MyObj& refa = oa; // expected-warning {{stack memory associated with local variable 'oa' is returned}} + const MyObj& refb = ob; // expected-warning {{stack memory associated with local variable 'ob' is returned}} return &MaxT(refa, refb); // expected-note 2 {{returned here}} } const MyObj& call_max_with_ref_obj_return_ref_error() { MyObj oa, ob; - const MyObj& refa = oa; // expected-warning {{address of stack memory is returned later}} - const MyObj& refb = ob; // expected-warning {{address of stack memory is returned later}} + const MyObj& refa = oa; // expected-warning {{stack memory associated with local variable 'oa' is returned}} + const MyObj& refb = ob; // expected-warning {{stack memory associated with local variable 'ob' is returned}} return MaxT(refa, refb); // expected-note 2 {{returned here}} } @@ -1506,47 +1506,47 @@ const MyObj& call_max_with_ref_obj_no_error(const MyObj& a, const MyObj& b) { const View& call_max_with_view_with_error() { View va, vb; - return MaxT(va, // expected-warning {{address of stack memory is returned later}} + return MaxT(va, // expected-warning {{stack memory associated with local variable 'va' is returned}} // expected-note@-1 2 {{returned here}} - vb); // expected-warning {{address of stack memory is returned later}} + vb); // expected-warning {{stack memory associated with local variable 'vb' is returned}} } struct [[gsl::Pointer]] NonTrivialPointer { ~NonTrivialPointer(); }; const NonTrivialPointer& call_max_with_non_trivial_view_with_error() { NonTrivialPointer va, vb; - return MaxT(va, // expected-warning {{address of stack memory is returned later}} + return MaxT(va, // expected-warning {{stack memory associated with local variable 'va' is returned}} // expected-note@-1 2 {{returned here}} - vb); // expected-warning {{address of stack memory is returned later}} + vb); // expected-warning {{stack memory associated with local variable 'vb' is returned}} } namespace MultiPointerTypes { int** return_2p() { int a = 1; - int* b = &a; // expected-warning {{address of stack memory is returned later}} - int** c = &b; // expected-warning {{address of stack memory is returned later}} + int* b = &a; // expected-warning {{stack memory associated with local variable 'a' is returned}} + int** c = &b; // expected-warning {{stack memory associated with local variable 'b' is returned}} return c; // expected-note 2 {{returned here}} } int** return_2p_one_is_safe(int& a) { int* b = &a; - int** c = &b; // expected-warning {{address of stack memory is returned later}} + int** c = &b; // expected-warning {{stack memory associated with local variable 'b' is returned}} return c; // expected-note {{returned here}} } int*** return_3p() { int a = 1; - int* b = &a; // expected-warning {{address of stack memory is returned later}} - int** c = &b; // expected-warning {{address of stack memory is returned later}} - int*** d = &c; // expected-warning {{address of stack memory is returned later}} + int* b = &a; // expected-warning {{stack memory associated with local variable 'a' is returned}} + int** c = &b; // expected-warning {{stack memory associated with local variable 'b' is returned}} + int*** d = &c; // expected-warning {{stack memory associated with local variable 'c' is returned}} return d; // expected-note 3 {{returned here}} } View** return_view_p() { MyObj a; - View b = a; // expected-warning {{address of stack memory is returned later}} - View* c = &b; // expected-warning {{address of stack memory is returned later}} - View** d = &c; // expected-warning {{address of stack memory is returned later}} + View b = a; // expected-warning {{stack memory associated with local variable 'a' is returned}} + View* c = &b; // expected-warning {{stack memory associated with local variable 'b' is returned}} + View** d = &c; // expected-warning {{stack memory associated with local variable 'c' is returned}} return d; // expected-note 3 {{returned here}} } @@ -1670,24 +1670,24 @@ void bar() { namespace DereferenceViews { const MyObj& testDeref(MyObj obj) { - View v = obj; // expected-warning {{address of stack memory is returned later}} + View v = obj; // expected-warning {{stack memory associated with parameter 'obj' is returned}} return *v; // expected-note {{returned here}} } const MyObj* testDerefAddr(MyObj obj) { - View v = obj; // expected-warning {{address of stack memory is returned later}} + View v = obj; // expected-warning {{stack memory associated with parameter 'obj' is returned}} return &*v; // expected-note {{returned here}} } const MyObj* testData(MyObj obj) { - View v = obj; // expected-warning {{address of stack memory is returned later}} + View v = obj; // expected-warning {{stack memory associated with parameter 'obj' is returned}} return v.data(); // expected-note {{returned here}} } const int* testLifetimeboundAccessorOfMyObj(MyObj obj) { - View v = obj; // expected-warning {{address of stack memory is returned later}} + View v = obj; // expected-warning {{stack memory associated with parameter 'obj' is returned}} const MyObj* ptr = v.data(); return ptr->getData(); // expected-note {{returned here}} } const int* testLifetimeboundAccessorOfMyObjThroughDeref(MyObj obj) { - View v = obj; // expected-warning {{address of stack memory is returned later}} + View v = obj; // expected-warning {{stack memory associated with parameter 'obj' is returned}} return v->getData(); // expected-note {{returned here}} } } // namespace DereferenceViews @@ -1711,17 +1711,17 @@ It end() const [[clang::lifetimebound]]; MyObj Global; const MyObj& ContainerMyObjReturnRef(Container<MyObj> c) { - for (const MyObj& x : c) { // expected-warning {{address of stack memory is returned later}} + for (const MyObj& x : c) { // expected-warning {{stack memory associated with parameter 'c' is returned}} return x; // expected-note {{returned here}} } return Global; } View ContainerMyObjReturnView(Container<MyObj> c) { - for (const MyObj& x : c) { // expected-warning {{address of stack memory is returned later}} + for (const MyObj& x : c) { // expected-warning {{stack memory associated with parameter 'c' is returned}} return x; // expected-note {{returned here}} } - for (View x : c) { // expected-warning {{address of stack memory is returned later}} + for (View x : c) { // expected-warning {{stack memory associated with parameter 'c' is returned}} return x; // expected-note {{returned here}} } return Global; @@ -1849,12 +1849,12 @@ struct RefMember { std::string_view refMemberReturnView1(RefMember a) { return a.str_ref; } std::string_view refMemberReturnView2(RefMember a) { return *a.str_ptr; } -std::string_view refMemberReturnView3(RefMember a) { return a.str; } // expected-warning {{address of stack memory is returned later}} expected-note {{returned here}} +std::string_view refMemberReturnView3(RefMember a) { return a.str; } // expected-warning {{stack memory associated with parameter 'a' is returned}} expected-note {{returned here}} std::string& refMemberReturnRef1(RefMember a) { return a.str_ref; } std::string& refMemberReturnRef2(RefMember a) { return *a.str_ptr; } -std::string& refMemberReturnRef3(RefMember a) { return a.str; } // expected-warning {{address of stack memory is returned later}} expected-note {{returned here}} +std::string& refMemberReturnRef3(RefMember a) { return a.str; } // expected-warning {{stack memory associated with parameter 'a' is returned}} expected-note {{returned here}} std::string_view refViewMemberReturnView1(RefMember a) { return a.view; } -std::string_view& refViewMemberReturnView2(RefMember a) { return a.view; } // expected-warning {{address of stack memory is returned later}} expected-note {{returned here}} +std::string_view& refViewMemberReturnView2(RefMember a) { return a.view; } // expected-warning {{stack memory associated with parameter 'a' is returned}} expected-note {{returned here}} std::string_view refViewMemberReturnRefView1(RefMember a) { return a.view_ref; } std::string_view& refViewMemberReturnRefView2(RefMember a) { return a.view_ref; } } // namespace field_access @@ -1908,16 +1908,16 @@ struct [[gsl::Pointer]] View { View test1(std::string a) { // Make sure we handle CXXBindTemporaryExpr of view types. - return View(a); // expected-warning {{address of stack memory is returned later}} expected-note {{returned here}} + return View(a); // expected-warning {{stack memory associated with parameter 'a' is returned}} expected-note {{returned here}} } View test2(std::string a) { - View b = View(a); // expected-warning {{address of stack memory is returned later}} + View b = View(a); // expected-warning {{stack memory associated with parameter 'a' is returned}} return b; // expected-note {{returned here}} } View test3(std::string a) { - const View& b = View(a); // expected-warning {{address of stack memory is returned later}} + const View& b = View(a); // expected-warning {{stack memory associated with parameter 'a' is returned}} return b; // expected-note {{returned here}} } } // namespace non_trivial_views @@ -1963,7 +1963,7 @@ void test_optional_view_arrow() { namespace lambda_captures { auto return_ref_capture() { int local = 1; - auto lambda = [&local]() { return local; }; // expected-warning {{address of stack memory is returned later}} + auto lambda = [&local]() { return local; }; // expected-warning {{stack memory associated with local variable 'local' is returned}} return lambda; // expected-note {{returned here}} } @@ -1981,7 +1981,7 @@ auto capture_int_by_value() { auto capture_view_by_value() { MyObj obj; - View v(obj); // expected-warning {{address of stack memory is returned later}} + View v(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} auto lambda = [v]() { return v; }; return lambda; // expected-note {{returned here}} } @@ -1996,57 +1996,57 @@ void capture_view_by_value_safe() { auto capture_pointer_by_ref() { MyObj obj; MyObj* p = &obj; - auto lambda = [&p]() { return p; }; // expected-warning {{address of stack memory is returned later}} + auto lambda = [&p]() { return p; }; // expected-warning {{stack memory associated with local variable 'p' is returned}} return lambda; // expected-note {{returned here}} } auto capture_multiple() { int a, b; auto lambda = [ - &a, // expected-warning {{address of stack memory is returned later}} - &b // expected-warning {{address of stack memory is returned later}} + &a, // expected-warning {{stack memory associated with local variable 'a' is returned}} + &b // expected-warning {{stack memory associated with local variable 'b' is returned}} ]() { return a + b; }; return lambda; // expected-note 2 {{returned here}} } auto capture_raw_pointer_by_value() { int x; - int* p = &x; // expected-warning {{address of stack memory is returned later}} + int* p = &x; // expected-warning {{stack memory associated with local variable 'x' is returned}} auto lambda = [p]() { return p; }; return lambda; // expected-note {{returned here}} } auto capture_raw_pointer_init_capture() { int x; - int* p = &x; // expected-warning {{address of stack memory is returned later}} + int* p = &x; // expected-warning {{stack memory associated with local variable 'x' is returned}} auto lambda = [q = p]() { return q; }; return lambda; // expected-note {{returned here}} } auto capture_view_init_capture() { MyObj obj; - View v(obj); // expected-warning {{address of stack memory is returned later}} + View v(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} auto lambda = [w = v]() { return w; }; return lambda; // expected-note {{returned here}} } auto capture_lambda() { int x; - auto inner = [&x]() { return x; }; // expected-warning {{address of stack memory is returned later}} + auto inner = [&x]() { return x; }; // expected-warning {{stack memory associated with local variable 'x' is returned}} auto outer = [inner]() { return inner(); }; return outer; // expected-note {{returned here}} } auto return_copied_lambda() { int local = 1; - auto lambda = [&local]() { return local; }; // expected-warning {{address of stack memory is returned later}} + auto lambda = [&local]() { return local; }; // expected-warning {{stack memory associated with local variable 'local' is returned}} auto lambda_copy = lambda; return lambda_copy; // expected-note {{returned here}} } auto implicit_ref_capture() { int local = 1; - auto lambda = [&]() { return local; }; // expected-warning {{address of stack memory is returned later}} + auto lambda = [&]() { return local; }; // expected-warning {{stack memory associated with local variable 'local' is returned}} return lambda; // expected-note {{returned here}} } @@ -2055,20 +2055,20 @@ auto implicit_ref_capture() { // can point to the same source location. auto implicit_ref_capture_multiple() { int local = 1, local2 = 2; - auto lambda = [&]() { return local + local2; }; // expected-warning 2 {{address of stack memory is returned later}} + auto lambda = [&]() { return local + local2; }; // expected-warning {{stack memory associated with local variable 'local2' is returned}} expected-warning {{stack memory associated with local variable 'local' is returned}} return lambda; // expected-note 2 {{returned here}} } auto implicit_value_capture() { MyObj obj; - View v(obj); // expected-warning {{address of stack memory is returned later}} + View v(obj); // expected-warning {{stack memory associated with local variable 'obj' is returned}} auto lambda = [=]() { return v; }; return lambda; // expected-note {{returned here}} } auto* pointer_to_lambda_outlives() { auto lambda = []() { return 42; }; - return λ // expected-warning {{address of stack memory is returned later}} \ + return λ // expected-warning {{stack memory associated with local variable 'lambda' is returned}} \ // expected-note {{returned here}} } @@ -2093,15 +2093,15 @@ auto capture_static_address_by_value() { auto capture_static_address_by_ref() { static int local = 1; int* p = &local; - auto lambda = [&p]() { return p; }; // expected-warning {{address of stack memory is returned later}} + auto lambda = [&p]() { return p; }; // expected-warning {{stack memory associated with local variable 'p' is returned}} return lambda; // expected-note {{returned here}} } auto capture_multilevel_pointer() { int x; - int *p = &x; // expected-warning {{address of stack memory is returned later}} - int **q = &p; // expected-warning {{address of stack memory is returned later}} - int ***r = &q; // expected-warning {{address of stack memory is returned later}} + int *p = &x; // expected-warning {{stack memory associated with local variable 'x' is returned}} + int **q = &p; // expected-warning {{stack memory associated with local variable 'p' is returned}} + int ***r = &q; // expected-warning {{stack memory associated with local variable 'q' is returned}} auto lambda = [=]() { return *p + **q + ***r; }; return lambda; // expected-note 3 {{returned here}} } @@ -2168,7 +2168,7 @@ void element_use_after_scope() { int* element_use_after_return() { int a[10]{}; - int* p = &a[0]; // expected-warning {{address of stack memory is returned later}} + int* p = &a[0]; // expected-warning {{stack memory associated with local variable 'a' is returned}} return p; // expected-note {{returned here}} } @@ -2231,7 +2231,7 @@ void reversed_subscript_use_after_scope() { int* return_decayed_array() { int a[10]{}; - int *p = a; // expected-warning {{address of stack memory is returned later}} + int *p = a; // expected-warning {{stack memory associated with local variable 'a' is returned}} return p; // expected-note {{returned here}} } @@ -2377,7 +2377,7 @@ void same_scope() { S copy_propagation() { std::string str{"abc"}; - S a = getS(str); // expected-warning {{address of stack memory is returned later}} + S a = getS(str); // expected-warning {{stack memory associated with local variable 'str' is returned}} S b = a; return b; // expected-note {{returned here}} } @@ -2421,7 +2421,7 @@ S getS2(const std::string &a [[clang::lifetimebound]], const std::string &b [[cl S multiple_lifetimebound_params() { std::string str{"abc"}; - S s = getS2(str, std::string("temp")); // expected-warning {{address of stack memory is returned later}} \ + S s = getS2(str, std::string("temp")); // expected-warning {{stack memory associated with local variable 'str' is returned}} \ // expected-warning {{object whose reference is captured does not live long enough}} \ // expected-note {{destroyed here}} return s; // expected-note {{returned here}} \ @@ -2539,7 +2539,7 @@ DefaultedOuter getDefaultedOuter(const std::string &s [[clang::lifetimebound]]); // pattern does not fit the ownership model this analysis supports. DefaultedOuter nested_defaulted_outer_with_user_defined_inner() { std::string str{"abc"}; - DefaultedOuter o = getDefaultedOuter(str); // expected-warning {{address of stack memory is returned later}} + DefaultedOuter o = getDefaultedOuter(str); // expected-warning {{stack memory associated with local variable 'str' is returned}} DefaultedOuter copy = o; return copy; // expected-note {{returned here}} } @@ -2571,7 +2571,7 @@ std::vector<std::string_view> createViews(const std::string &s [[clang::lifetime std::span<std::string_view> owner_to_pointer_via_gsl_construction() { std::string local; auto views = createViews(local); - return views; // expected-warning {{address of stack memory is returned later}} \ + return views; // expected-warning {{stack memory associated with local variable 'views' is returned}} \ // expected-note {{returned here}} } @@ -2586,7 +2586,7 @@ void owner_return_unique_ptr_s() { std::string_view return_dangling_view_through_owner() { std::string local; auto ups = getUniqueS(local); - S* s = ups.get(); // expected-warning {{address of stack memory is returned later}} + S* s = ups.get(); // expected-warning {{stack memory associated with local variable 'ups' is returned}} std::string_view sv = s->getData(); return sv; // expected-note {{returned here}} } @@ -2683,12 +2683,12 @@ int *constexpr_dead_nested(int *num) { int *constexpr_live_false(int *num) { int local = 0; - return kFalse ? num : f(&local); // expected-warning {{address of stack memory is returned later}} // expected-note {{returned here}} + return kFalse ? num : f(&local); // expected-warning {{stack memory associated with local variable 'local' is returned}} // expected-note {{returned here}} } int *constexpr_live_nested(int *num) { int local = 0; - return kTrue ? (kFalse ? num : f(&local)) : num; // expected-warning {{address of stack memory is returned later}} // expected-note {{returned here}} + return kTrue ? (kFalse ? num : f(&local)) : num; // expected-warning {{stack memory associated with local variable 'local' is returned}} // expected-note {{returned here}} } int *noreturn_dead_false(bool cond, int *num) { int local = 0; @@ -3221,20 +3221,20 @@ namespace callable_wrappers { std::function<void()> direct_return() { int x; - return [&x]() { (void)x; }; // expected-warning {{address of stack memory is returned later}} \ + return [&x]() { (void)x; }; // expected-warning {{stack memory associated with local variable 'x' is returned}} \ // expected-note {{returned here}} } std::function<void()> copy_function() { int x; - std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{address of stack memory is returned later}} + std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{stack memory associated with local variable 'x' is returned}} std::function<void()> f2 = f; return f2; // expected-note {{returned here}} } std::function<void()> copy_assign() { int x; - std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{address of stack memory is returned later}} + std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{stack memory associated with local variable 'x' is returned}} std::function<void()> f2 = []() {}; f2 = f; return f2; // expected-note {{returned here}} @@ -3242,7 +3242,7 @@ std::function<void()> copy_assign() { std::function<void()> chained_copy_assign() { int x; - std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{address of stack memory is returned later}} + std::function<void()> f = [&x]() { (void)x; }; // expected-warning {{stack memory associated with local variable 'x' is returned}} std::function<void()> f2 = []() {}; std::function<void()> f3 = []() {}; f3 = f2 = f; @@ -3264,7 +3264,7 @@ std::function<void()> reassign_safe_then_unsafe() { static int safe = 1; int local = 2; std::function<void()> f = []() { (void)safe; }; - f = [&local]() { (void)local; }; // expected-warning {{address of stack memory is returned later}} + f = [&local]() { (void)local; }; // expected-warning {{stack memory associated with local variable 'local' is returned}} return f; // expected-note {{returned here}} } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
