https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/200031
>From 94ffdc0b69a201ce3981a81956b56a31d63cc6f8 Mon Sep 17 00:00:00 2001 From: NeKon69 <[email protected]> Date: Wed, 27 May 2026 21:59:25 +0300 Subject: [PATCH] [LifetimeSafety] Imrpove diagnostics for use-after-scope --- .../clang/Basic/DiagnosticSemaKinds.td | 6 +- clang/lib/Sema/SemaLifetimeSafety.h | 10 +- .../Sema/warn-lifetime-analysis-nocfg.cpp | 88 +++--- .../Sema/warn-lifetime-safety-cfg-bailout.cpp | 4 +- .../Sema/warn-lifetime-safety-suggestions.cpp | 12 +- clang/test/Sema/warn-lifetime-safety.cpp | 283 +++++++++--------- 6 files changed, 203 insertions(+), 200 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e330ea03d0544..c4f16ffcfb649 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10964,11 +10964,11 @@ def warn_dangling_reference_captured_by_unknown : Warning< // Diagnostics based on the Lifetime safety analysis. def warn_lifetime_safety_use_after_scope : Warning< - "object whose reference is captured does not live long enough">, + "%0 does not live long enough">, InGroup<LifetimeSafetyUseAfterScope>, DefaultIgnore; def warn_lifetime_safety_use_after_scope_moved : Warning< - "object whose reference is captured may not live long enough. " - "This could be false positive as the storage may have been moved later">, + "%0 may not live long enough. " + "This could be a false positive as the storage may have been moved later">, InGroup<LifetimeSafetyUseAfterScopeMoved>, DefaultIgnore; def warn_lifetime_safety_use_after_free : Warning< diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h index 0305510c1a233..2c4cfeab845c9 100644 --- a/clang/lib/Sema/SemaLifetimeSafety.h +++ b/clang/lib/Sema/SemaLifetimeSafety.h @@ -63,10 +63,12 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper { void reportUseAfterScope(const Expr *IssueExpr, const Expr *UseExpr, const Expr *MovedExpr, SourceLocation FreeLoc) override { - S.Diag(IssueExpr->getExprLoc(), - MovedExpr ? diag::warn_lifetime_safety_use_after_scope_moved - : diag::warn_lifetime_safety_use_after_scope) - << IssueExpr->getSourceRange(); + unsigned DiagID = MovedExpr + ? diag::warn_lifetime_safety_use_after_scope_moved + : diag::warn_lifetime_safety_use_after_scope; + + S.Diag(IssueExpr->getExprLoc(), DiagID) + << getDiagSubjectDescription(IssueExpr) << IssueExpr->getSourceRange(); if (MovedExpr) S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here) << MovedExpr->getSourceRange(); diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index 9c53129ff707d..fa9cd33cc2d61 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -75,7 +75,7 @@ struct Y { }; void dangligGslPtrFromTemporary() { - MyIntPointer p = Y{}.a; // cfg-warning {{object whose reference is captured does not live long enough}} \ + MyIntPointer p = Y{}.a; // cfg-warning {{local temporary object does not live long enough}} \ // cfg-note {{destroyed here}} (void)p; // cfg-note {{later used here}} } @@ -145,32 +145,32 @@ MyLongPointerFromConversion global2; void initLocalGslPtrWithTempOwner() { MyIntPointer p = MyIntOwner{}; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(p); // cfg-note {{later used here}} MyIntPointer pp = p = MyIntOwner{}; // expected-warning {{object backing the pointer 'p' will be}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(p, pp); // cfg-note {{later used here}} p = MyIntOwner{}; // expected-warning {{object backing the pointer 'p' }} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(p); // cfg-note {{later used here}} pp = p; // no warning use(p, pp); global = MyIntOwner{}; // expected-warning {{object backing the pointer 'global' }} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(global); // cfg-note {{later used here}} MyLongPointerFromConversion p2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(p2); // cfg-note {{later used here}} p2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer 'p2' }} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} global2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer 'global2' }} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(global2, p2); // cfg-note 2 {{later used here}} } @@ -193,7 +193,7 @@ struct Unannotated { void modelIterators() { std::vector<int>::iterator it = std::vector<int>().begin(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} (void)it; // cfg-note {{later used here}} } @@ -241,11 +241,11 @@ int &danglingRawPtrFromLocal3() { // GH100384 std::string_view containerWithAnnotatedElements() { std::string_view c1 = std::vector<std::string>().at(0); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(c1); // cfg-note {{later used here}} c1 = std::vector<std::string>().at(0); // expected-warning {{object backing the pointer}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(c1); // cfg-note {{later used here}} // no warning on constructing from gsl-pointer @@ -306,23 +306,23 @@ std::string_view danglingRefToOptionalFromTemp4() { void danglingReferenceFromTempOwner() { int &&r = *std::optional<int>(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} // https://github.com/llvm/llvm-project/issues/175893 int &&r2 = *std::optional<int>(5); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} // https://github.com/llvm/llvm-project/issues/175893 int &&r3 = std::optional<int>(5).value(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} const int &r4 = std::vector<int>().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} int &&r5 = std::vector<int>().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(r, r2, r3, r4, r5); // cfg-note 5 {{later used here}} std::string_view sv = *getTempOptStr(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(sv); // cfg-note {{later used here}} } @@ -333,7 +333,7 @@ void testLoops() { for (auto i : getTempVec()) // ok ; for (auto i : *getTempOptVec()) // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} cfg-note {{later used here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} cfg-note {{later used here}} ; } @@ -395,18 +395,18 @@ void handleGslPtrInitsThroughReference2() { void handleTernaryOperator(bool cond) { std::basic_string<char> def; std::basic_string_view<char> v = cond ? def : ""; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(v); // cfg-note {{later used here}} } std::string operator+(std::string_view s1, std::string_view s2); void danglingStringviewAssignment(std::string_view a1, std::string_view a2) { a1 = std::string(); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(a1); // cfg-note {{later used here}} a2 = a1 + a1; // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(a2); // cfg-note {{later used here}} } @@ -601,7 +601,7 @@ struct UrlAnalyzed { std::string StrCat(std::string_view, std::string_view); void test1() { UrlAnalyzed url(StrCat("abc", "bcd")); // expected-warning {{object backing the pointer will be destroyed}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} \ + // cfg-warning {{local temporary object does not live long enough}} \ // cfg-note {{destroyed here}} use(url); // cfg-note {{later used here}} } @@ -610,7 +610,7 @@ std::string_view ReturnStringView(std::string_view abc [[clang::lifetimebound]]) void test() { std::string_view svjkk1 = ReturnStringView(StrCat("bar", "x")); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(svjkk1); // cfg-note {{later used here}} } } // namespace GH100549 @@ -844,7 +844,7 @@ namespace GH118064{ void test() { auto y = std::set<int>{}.begin(); // expected-warning {{object backing the pointer}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(y); // cfg-note {{later used here}} } } // namespace GH118064 @@ -859,10 +859,10 @@ std::string_view TakeStr(std::string abc [[clang::lifetimebound]]); std::string_view test1_1() { std::string_view t1 = Ref(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(t1); // cfg-note {{later used here}} t1 = Ref(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} @@ -870,10 +870,10 @@ std::string_view test1_1() { std::string_view test1_2() { std::string_view t2 = TakeSv(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(t2); // cfg-note {{later used here}} t2 = TakeSv(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(t2); // cfg-note {{later used here}} return TakeSv(std::string()); // expected-warning {{returning address}} \ @@ -882,10 +882,10 @@ std::string_view test1_2() { std::string_view test1_3() { std::string_view t3 = TakeStrRef(std::string()); // expected-warning {{temporary}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(t3); // cfg-note {{later used here}} t3 = TakeStrRef(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} @@ -907,10 +907,10 @@ struct Foo { }; std::string_view test2_1(Foo<std::string> r1, Foo<std::string_view> r2) { std::string_view t1 = Foo<std::string>().get(); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(t1); // cfg-note {{later used here}} t1 = Foo<std::string>().get(); // expected-warning {{object backing}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object 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 {{stack memory associated with parameter 'r1' is returned}} cfg-note {{returned here}} @@ -939,9 +939,9 @@ struct [[gsl::Pointer]] Pointer { Pointer(const Bar & bar [[clang::lifetimebound]]); }; Pointer test3(Bar bar) { - Pointer p = Pointer(Bar()); // expected-warning {{temporary}} cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + Pointer p = Pointer(Bar()); // expected-warning {{temporary}} cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} 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}} + p = Pointer(Bar()); // expected-warning {{object backing}} cfg-warning {{local temporary object 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 {{stack memory associated with parameter 'bar' is returned}} cfg-note {{returned here}} } @@ -1028,9 +1028,9 @@ void operator_star_arrow_reference() { const std::string& r = *v.begin(); auto temporary = []() { return std::vector<std::string>{{"1"}}; }; - const char* x = temporary().begin()->data(); // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} - const char* y = (*temporary().begin()).data(); // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} - const std::string& z = (*temporary().begin()); // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + const char* x = temporary().begin()->data(); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + const char* y = (*temporary().begin()).data(); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + const std::string& z = (*temporary().begin()); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(p, q, r, x, y, z); // cfg-note 3 {{later used here}} } @@ -1042,9 +1042,9 @@ void operator_star_arrow_of_iterators_false_positive_no_cfg_analysis() { const std::string& r = (*v.begin()).second; auto temporary = []() { return std::vector<std::pair<int, std::string>>{{1, "1"}}; }; - const char* x = temporary().begin()->second.data(); // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} - const char* y = (*temporary().begin()).second.data(); // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} - const std::string& z = (*temporary().begin()).second; // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + const char* x = temporary().begin()->second.data(); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + const char* y = (*temporary().begin()).second.data(); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + const std::string& z = (*temporary().begin()).second; // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(p, q, r, x, y, z); // cfg-note 3 {{later used here}} } @@ -1094,17 +1094,17 @@ std::string_view foo(std::string_view sv [[clang::lifetimebound]]); void test1() { std::string_view k1 = S().sv; // OK std::string_view k2 = S().s; // expected-warning {{object backing the pointer will}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} std::string_view k3 = Q().get()->sv; // OK std::string_view k4 = Q().get()->s; // expected-warning {{object backing the pointer will}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} std::string_view lb1 = foo(S().s); // expected-warning {{object backing the pointer will}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} std::string_view lb2 = foo(Q().get()->s); // expected-warning {{object backing the pointer will}} \ - // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} use(k1, k2, k3, k4, lb1, lb2); // cfg-note 4 {{later used here}} } diff --git a/clang/test/Sema/warn-lifetime-safety-cfg-bailout.cpp b/clang/test/Sema/warn-lifetime-safety-cfg-bailout.cpp index 7c5d61e23e710..6f2c06fdf6a72 100644 --- a/clang/test/Sema/warn-lifetime-safety-cfg-bailout.cpp +++ b/clang/test/Sema/warn-lifetime-safety-cfg-bailout.cpp @@ -27,7 +27,7 @@ void single_block_cfg() { MyObj* p; { MyObj s; - p = &s; // bailout-warning {{object whose reference is captured does not live long enough}} + p = &s; // bailout-warning {{local variable 's' does not live long enough}} } // bailout-note {{destroyed here}} (void)*p; // bailout-note {{later used here}} } @@ -39,7 +39,7 @@ void multiple_block_cfg() { { if (a > 5) { MyObj s; - p = &s; // nobailout-warning {{object whose reference is captured does not live long enough}} + p = &s; // nobailout-warning {{local variable 's' does not live long enough}} } else { // nobailout-note {{destroyed here}} p = &safe; } diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp index 24aacc9480533..94b1febbcef93 100644 --- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp +++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp @@ -276,19 +276,19 @@ View return_view_field(const ViewProvider& v) { // expected-warning {{paramet } void test_get_on_temporary_pointer() { - const ReturnsSelf* s_ref = &ReturnsSelf().get(); // expected-warning {{object whose reference is captured does not live long enough}}. + const ReturnsSelf* s_ref = &ReturnsSelf().get(); // expected-warning {{local temporary object does not live long enough}}. // expected-note@-1 {{destroyed here}} (void)s_ref; // expected-note {{later used here}} } void test_get_on_temporary_ref() { - const ReturnsSelf& s_ref = ReturnsSelf().get(); // expected-warning {{object whose reference is captured does not live long enough}}. + const ReturnsSelf& s_ref = ReturnsSelf().get(); // expected-warning {{local temporary object does not live long enough}}. // expected-note@-1 {{destroyed here}} (void)s_ref; // expected-note {{later used here}} } void test_getView_on_temporary() { - View sv = ViewProvider{1}.getView(); // expected-warning {{object whose reference is captured does not live long enough}}. + View sv = ViewProvider{1}.getView(); // expected-warning {{local temporary object does not live long enough}}. // expected-note@-1 {{destroyed here}} (void)sv; // expected-note {{later used here}} } @@ -599,7 +599,7 @@ void uaf_via_inferred_lifetimebound() { std::function<void()> f = []() {}; { int local; - f = return_lambda_capturing_param(local); // expected-warning {{object whose reference is captured does not live long enough}} + f = return_lambda_capturing_param(local); // expected-warning {{local variable 'local' does not live long enough}} } // expected-note {{destroyed here}} (void)f; // expected-note {{later used here}} } @@ -622,7 +622,7 @@ void test_inference() { std::unique_ptr<LifetimeBoundCtor> ptr; { MyObj obj; - ptr = create_target(obj); // expected-warning {{object whose reference is captured does not live long enough}} + ptr = create_target(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)ptr; // expected-note {{later used here}} } @@ -635,7 +635,7 @@ View* MakeView(const MyObj& in) { // expected-warning {{parameter in intra-TU fu } void test_new_allocation() { - View* v = MakeView(MyObj{}); // expected-warning {{object whose reference is captured does not live long enough}} \ + View* v = MakeView(MyObj{}); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} } diff --git a/clang/test/Sema/warn-lifetime-safety.cpp b/clang/test/Sema/warn-lifetime-safety.cpp index d5f558c7918b3..936568deeb150 100644 --- a/clang/test/Sema/warn-lifetime-safety.cpp +++ b/clang/test/Sema/warn-lifetime-safety.cpp @@ -54,7 +54,7 @@ void simple_case() { MyObj* p; { MyObj s; - p = &s; // expected-warning {{object whose reference is captured does not live long enough}} + p = &s; // expected-warning {{local variable 's' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -63,7 +63,7 @@ void simple_case_gsl() { View v; { MyObj s; - v = s; // expected-warning {{object whose reference is captured does not live long enough}} + v = s; // expected-warning {{local variable 's' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -101,7 +101,7 @@ void propagation_gsl() { View v1, v2; { MyObj s; - v1 = s; // expected-warning {{object whose reference is captured does not live long enough}} + v1 = s; // expected-warning {{local variable 's' does not live long enough}} v2 = v1; } // expected-note {{destroyed here}} v2.use(); // expected-note {{later used here}} @@ -170,11 +170,11 @@ void single_pointer_multiple_loans_gsl(bool cond) { View v; if (cond){ MyObj s; - v = s; // expected-warning {{object whose reference is captured does not live long enough}} + v = s; // expected-warning {{local variable 's' does not live long enough}} } // expected-note {{destroyed here}} else { MyObj t; - v = t; // expected-warning {{object whose reference is captured does not live long enough}} + v = t; // expected-warning {{local variable 't' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note 2 {{later used here}} } @@ -184,7 +184,7 @@ void if_branch(bool cond) { MyObj* p = &safe; if (cond) { MyObj temp; - p = &temp; // expected-warning {{object whose reference is captured does not live long enough}} + p = &temp; // expected-warning {{local variable 'temp' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -194,7 +194,7 @@ void if_branch_potential(bool cond) { MyObj* p = &safe; if (cond) { MyObj temp; - p = &temp; // expected-warning {{object whose reference is captured does not live long enough}} + p = &temp; // expected-warning {{local variable 'temp' does not live long enough}} } // expected-note {{destroyed here}} if (!cond) (void)*p; // expected-note {{later used here}} @@ -207,7 +207,7 @@ void if_branch_gsl(bool cond) { View v = safe; if (cond) { MyObj temp; - v = temp; // expected-warning {{object whose reference is captured does not live long enough}} + v = temp; // expected-warning {{local variable 'temp' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -288,7 +288,7 @@ void for_loop_gsl() { View v = safe; for (int i = 0; i < 1; ++i) { MyObj s; - v = s; // expected-warning {{object whose reference is captured does not live long enough}} + v = s; // expected-warning {{local variable 's' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -323,7 +323,7 @@ void loop_with_break_gsl(bool cond) { for (int i = 0; i < 10; ++i) { if (cond) { MyObj temp; - v = temp; // expected-warning {{object whose reference is captured does not live long enough}} + v = temp; // expected-warning {{local variable 'temp' does not live long enough}} break; // expected-note {{destroyed here}} } } @@ -381,7 +381,7 @@ void switch_potential(int mode) { switch (mode) { case 1: { MyObj temp; - p = &temp; // expected-warning {{object whose reference is captured does not live long enough}} + p = &temp; // expected-warning {{local variable 'temp' does not live long enough}} break; // expected-note {{destroyed here}} } case 2: { @@ -422,17 +422,17 @@ void switch_gsl(int mode) { switch (mode) { case 1: { MyObj temp1; - v = temp1; // expected-warning {{object whose reference is captured does not live long enough}} + v = temp1; // expected-warning {{local variable 'temp1' does not live long enough}} break; // expected-note {{destroyed here}} } case 2: { MyObj temp2; - v = temp2; // expected-warning {{object whose reference is captured does not live long enough}} + v = temp2; // expected-warning {{local variable 'temp2' does not live long enough}} break; // expected-note {{destroyed here}} } default: { MyObj temp3; - v = temp3; // expected-warning {{object whose reference is captured does not live long enough}} + v = temp3; // expected-warning {{local variable 'temp3' does not live long enough}} break; // expected-note {{destroyed here}} } } @@ -458,7 +458,7 @@ void trivial_int_uaf() { int * a; { int b = 1; - a = &b; // expected-warning {{object whose reference is captured does not live long enough}} + a = &b; // expected-warning {{local variable 'b' does not live long enough}} } // expected-note {{destroyed here}} (void)*a; // expected-note {{later used here}} } @@ -467,7 +467,7 @@ void trivial_class_uaf() { TriviallyDestructedClass* ptr; { TriviallyDestructedClass s; - ptr = &s; // expected-warning {{object whose reference is captured does not live long enough}} + ptr = &s; // expected-warning {{local variable 's' does not live long enough}} } // expected-note {{destroyed here}} (void)ptr; // expected-note {{later used here}} } @@ -659,7 +659,7 @@ void test_view_pointer() { View* vp; { View v; - vp = &v; // expected-warning {{object whose reference is captured does not live long enough}} + vp = &v; // expected-warning {{local variable 'v' does not live long enough}} } // expected-note {{destroyed here}} vp->use(); // expected-note {{later used here}} } @@ -668,7 +668,7 @@ void test_view_double_pointer() { View** vpp; { View* vp = nullptr; - vpp = &vp; // expected-warning {{object whose reference is captured does not live long enough}} + vpp = &vp; // expected-warning {{local variable 'vp' does not live long enough}} } // expected-note {{destroyed here}} (**vpp).use(); // expected-note {{later used here}} } @@ -695,7 +695,7 @@ void test_lifetimebound_multi_level() { { int* p = nullptr; int** pp = &p; - int*** ppp = &pp; // expected-warning {{object whose reference is captured does not live long enough}} + int*** ppp = &pp; // expected-warning {{local variable 'pp' does not live long enough}} result = return_inner_ptr_addr(ppp); } // expected-note {{destroyed here}} (void)**result; // expected-note {{used here}} @@ -729,7 +729,7 @@ MyObj* uaf_before_uar() { MyObj* p; { MyObj local_obj; - p = &local_obj; // expected-warning {{object whose reference is captured does not live long enough}} + p = &local_obj; // expected-warning {{local variable 'local_obj' does not live long enough}} } // expected-note {{destroyed here}} return p; // expected-note {{later used here}} } @@ -819,7 +819,7 @@ void lifetimebound_simple_function() { View v; { MyObj obj; - v = Identity(obj); // expected-warning {{object whose reference is captured does not live long enough}} + v = Identity(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -829,8 +829,8 @@ void lifetimebound_multiple_args_definite() { { MyObj obj1, obj2; v = Choose(true, - obj1, // expected-warning {{object whose reference is captured does not live long enough}} - obj2); // expected-warning {{object whose reference is captured does not live long enough}} + obj1, // expected-warning {{local variable 'obj1' does not live long enough}} + obj2); // expected-warning {{local variable 'obj2' does not live long enough}} } // expected-note 2 {{destroyed here}} v.use(); // expected-note 2 {{later used here}} } @@ -843,8 +843,8 @@ void lifetimebound_multiple_args_potential(bool cond) { if (cond) { MyObj obj2; v = Choose(true, - obj1, // expected-warning {{object whose reference is captured does not live long enough}} - obj2); // expected-warning {{object whose reference is captured does not live long enough}} + obj1, // expected-warning {{local variable 'obj1' does not live long enough}} + obj2); // expected-warning {{local variable 'obj2' does not live long enough}} } // expected-note {{destroyed here}} } // expected-note {{destroyed here}} v.use(); // expected-note 2 {{later used here}} @@ -855,7 +855,7 @@ void lifetimebound_mixed_args() { View v; { MyObj obj1, obj2; - v = SelectFirst(obj1, // expected-warning {{object whose reference is captured does not live long enough}} + v = SelectFirst(obj1, // expected-warning {{local variable 'obj1' does not live long enough}} obj2); } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} @@ -871,7 +871,7 @@ void lifetimebound_member_function() { View v; { MyObj obj; - v = obj.getView(); // expected-warning {{object whose reference is captured does not live long enough}} + v = obj.getView(); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -886,7 +886,7 @@ void lifetimebound_conversion_operator() { View v; { LifetimeBoundConversionView obj; - v = obj; // expected-warning {{object whose reference is captured does not live long enough}} + v = obj; // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -895,7 +895,7 @@ void lifetimebound_chained_calls() { View v; { MyObj obj; - v = Identity(Identity(Identity(obj))); // expected-warning {{object whose reference is captured does not live long enough}} + v = Identity(Identity(Identity(obj))); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -904,7 +904,7 @@ void lifetimebound_with_pointers() { MyObj* ptr; { MyObj obj; - ptr = GetPointer(obj); // expected-warning {{object whose reference is captured does not live long enough}} + ptr = GetPointer(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)*ptr; // expected-note {{later used here}} } @@ -933,7 +933,7 @@ void lifetimebound_partial_safety(bool cond) { MyObj temp_obj; v = Choose(true, safe_obj, - temp_obj); // expected-warning {{object whose reference is captured does not live long enough}} + temp_obj); // expected-warning {{local variable 'temp_obj' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -944,7 +944,7 @@ void lifetimebound_return_reference() { const MyObj* ptr; { MyObj obj; - View temp_v = obj; // expected-warning {{object whose reference is captured does not live long enough}} + View temp_v = obj; // expected-warning {{local variable 'obj' does not live long enough}} const MyObj& ref = GetObject(temp_v); ptr = &ref; } // expected-note {{destroyed here}} @@ -963,7 +963,7 @@ void lifetimebound_ctor() { LifetimeBoundCtor v; { MyObj obj; - v = obj; // expected-warning {{object whose reference is captured does not live long enough}} + v = obj; // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} } @@ -972,7 +972,7 @@ void lifetimebound_ctor_functional_cast() { LifetimeBoundCtor v; { MyObj obj; - v = LifetimeBoundCtor(obj); // expected-warning {{object whose reference is captured does not live long enough}} + v = LifetimeBoundCtor(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} } @@ -981,7 +981,7 @@ void lifetimebound_ctor_c_style_cast() { LifetimeBoundCtor v; { MyObj obj; - v = (LifetimeBoundCtor)(obj); // expected-warning {{object whose reference is captured does not live long enough}} + v = (LifetimeBoundCtor)(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} } @@ -990,7 +990,7 @@ void lifetimebound_ctor_static_cast() { LifetimeBoundCtor v; { MyObj obj; - v = static_cast<LifetimeBoundCtor>(obj); // expected-warning {{object whose reference is captured does not live long enough}} + v = static_cast<LifetimeBoundCtor>(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} } @@ -999,7 +999,7 @@ void lifetimebound_make_unique() { std::unique_ptr<LifetimeBoundCtor> ptr; { MyObj obj; - ptr = std::make_unique<LifetimeBoundCtor>(obj); // tu-warning {{object whose reference is captured does not live long enough}} + ptr = std::make_unique<LifetimeBoundCtor>(obj); // tu-warning {{local variable 'obj' does not live long enough}} } // tu-note {{destroyed here}} (void)ptr; // tu-note {{later used here}} } @@ -1015,7 +1015,7 @@ void non_lifetimebound_make_unique() { } void lifetimebound_make_unique_temp() { - std::unique_ptr<LifetimeBoundCtor> ptr = std::make_unique<LifetimeBoundCtor>(MyObj()); // tu-warning {{object whose reference is captured does not live long enough}} \ + std::unique_ptr<LifetimeBoundCtor> ptr = std::make_unique<LifetimeBoundCtor>(MyObj()); // tu-warning {{local temporary object does not live long enough}} \ // tu-note {{destroyed here}} (void)ptr; // tu-note {{later used here}} } @@ -1053,7 +1053,7 @@ void lifetimebound_make_unique_multi_params() { MyObj obj_long; { MyObj obj_short; - ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_short, obj_long); // tu-warning {{object whose reference is captured does not live long enough}} + ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_short, obj_long); // tu-warning {{local variable 'obj_short' does not live long enough}} } // tu-note {{destroyed here}} (void)ptr; // tu-note {{later used here}} } @@ -1063,7 +1063,7 @@ void lifetimebound_make_unique_multi_params2() { MyObj obj_long; { MyObj obj_short; - ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_long, obj_short, 1); // tu-warning {{object whose reference is captured does not live long enough}} + ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_long, obj_short, 1); // tu-warning {{local variable 'obj_short' does not live long enough}} } // tu-note {{destroyed here}} (void)ptr; // tu-note {{later used here}} } @@ -1083,7 +1083,7 @@ void lifetimebound_make_unique_multi_params3_1() { MyObj obj_long; { MyObj obj_short; - ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_short, obj_long, 1.0); // tu-warning {{object whose reference is captured does not live long enough}} + ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_short, obj_long, 1.0); // tu-warning {{local variable 'obj_short' does not live long enough}} } // tu-note {{destroyed here}} (void)ptr; // tu-note {{later used here}} } @@ -1093,7 +1093,7 @@ void lifetimebound_make_unique_multi_params3_2() { MyObj obj_long; { MyObj obj_short; - ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_long, obj_short, 1.0); // tu-warning {{object whose reference is captured does not live long enough}} + ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_long, obj_short, 1.0); // tu-warning {{local variable 'obj_short' does not live long enough}} } // tu-note {{destroyed here}} (void)ptr; // tu-note {{later used here}} } @@ -1169,7 +1169,7 @@ void conditional_operator_one_unsafe_branch(bool cond) { MyObj* p = &safe; { MyObj temp; - p = cond ? &temp // expected-warning {{object whose reference is captured does not live long enough}} + p = cond ? &temp // expected-warning {{local variable 'temp' does not live long enough}} : &safe; } // expected-note {{destroyed here}} @@ -1185,8 +1185,8 @@ void conditional_operator_two_unsafe_branches(bool cond) { MyObj* p; { MyObj a, b; - p = cond ? &a // expected-warning {{object whose reference is captured does not live long enough}} - : &b; // expected-warning {{object whose reference is captured does not live long enough}} + p = cond ? &a // expected-warning {{local variable 'a' does not live long enough}} + : &b; // expected-warning {{local variable 'b' does not live long enough}} } // expected-note 2 {{destroyed here}} (void)*p; // expected-note 2 {{later used here}} } @@ -1195,10 +1195,10 @@ void conditional_operator_nested(bool cond) { MyObj* p; { MyObj a, b, c, d; - p = cond ? cond ? &a // expected-warning {{object whose reference is captured does not live long enough}}. - : &b // expected-warning {{object whose reference is captured does not live long enough}}. - : cond ? &c // expected-warning {{object whose reference is captured does not live long enough}}. - : &d; // expected-warning {{object whose reference is captured does not live long enough}}. + p = cond ? cond ? &a // expected-warning {{local variable 'a' does not live long enough}}. + : &b // expected-warning {{local variable 'b' does not live long enough}}. + : cond ? &c // expected-warning {{local variable 'c' does not live long enough}}. + : &d; // expected-warning {{local variable 'd' does not live long enough}}. } // expected-note 4 {{destroyed here}} (void)*p; // expected-note 4 {{later used here}} } @@ -1207,8 +1207,8 @@ void conditional_operator_lifetimebound(bool cond) { MyObj* p; { MyObj a, b; - p = Identity(cond ? &a // expected-warning {{object whose reference is captured does not live long enough}} - : &b); // expected-warning {{object whose reference is captured does not live long enough}} + p = Identity(cond ? &a // expected-warning {{local variable 'a' does not live long enough}} + : &b); // expected-warning {{local variable 'b' does not live long enough}} } // expected-note 2 {{destroyed here}} (void)*p; // expected-note 2 {{later used here}} } @@ -1217,8 +1217,8 @@ void conditional_operator_lifetimebound_nested(bool cond) { MyObj* p; { MyObj a, b; - p = Identity(cond ? Identity(&a) // expected-warning {{object whose reference is captured does not live long enough}} - : Identity(&b)); // expected-warning {{object whose reference is captured does not live long enough}} + p = Identity(cond ? Identity(&a) // expected-warning {{local variable 'a' does not live long enough}} + : Identity(&b)); // expected-warning {{local variable 'b' does not live long enough}} } // expected-note 2 {{destroyed here}} (void)*p; // expected-note 2 {{later used here}} } @@ -1227,10 +1227,10 @@ void conditional_operator_lifetimebound_nested_deep(bool cond) { MyObj* p; { MyObj a, b, c, d; - p = Identity(cond ? Identity(cond ? &a // expected-warning {{object whose reference is captured does not live long enough}} - : &b) // expected-warning {{object whose reference is captured does not live long enough}} - : Identity(cond ? &c // expected-warning {{object whose reference is captured does not live long enough}} - : &d)); // expected-warning {{object whose reference is captured does not live long enough}} + p = Identity(cond ? Identity(cond ? &a // expected-warning {{local variable 'a' does not live long enough}} + : &b) // expected-warning {{local variable 'b' does not live long enough}} + : Identity(cond ? &c // expected-warning {{local variable 'c' does not live long enough}} + : &d)); // expected-warning {{local variable 'd' does not live long enough}} } // expected-note 4 {{destroyed here}} (void)*p; // expected-note 4 {{later used here}} } @@ -1239,29 +1239,29 @@ void parentheses(bool cond) { MyObj* p; { MyObj a; - p = &((((a)))); // expected-warning {{object whose reference is captured does not live long enough}} + p = &((((a)))); // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} { MyObj a; - p = ((GetPointer((a)))); // expected-warning {{object whose reference is captured does not live long enough}} + p = ((GetPointer((a)))); // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} { MyObj a, b, c, d; - p = &(cond ? (cond ? a // expected-warning {{object whose reference is captured does not live long enough}}. - : b) // expected-warning {{object whose reference is captured does not live long enough}}. - : (cond ? c // expected-warning {{object whose reference is captured does not live long enough}}. - : d)); // expected-warning {{object whose reference is captured does not live long enough}}. + p = &(cond ? (cond ? a // expected-warning {{local variable 'a' does not live long enough}}. + : b) // expected-warning {{local variable 'b' does not live long enough}}. + : (cond ? c // expected-warning {{local variable 'c' does not live long enough}}. + : d)); // expected-warning {{local variable 'd' does not live long enough}}. } // expected-note 4 {{destroyed here}} (void)*p; // expected-note 4 {{later used here}} { MyObj a, b, c, d; - p = ((cond ? (((cond ? &a : &b))) // expected-warning 2 {{object whose reference is captured does not live long enough}}. - : &(((cond ? c : d))))); // expected-warning 2 {{object whose reference is captured does not live long enough}}. + p = ((cond ? (((cond ? &a : &b))) // expected-warning {{local variable 'b' does not live long enough}} expected-warning {{local variable 'a' does not live long enough}}. + : &(((cond ? c : d))))); // expected-warning {{local variable 'd' does not live long enough}} expected-warning {{local variable 'c' does not live long enough}}. } // expected-note 4 {{destroyed here}} (void)*p; // expected-note 4 {{later used here}} @@ -1269,20 +1269,20 @@ void parentheses(bool cond) { void use_temporary_after_destruction() { View a; - a = non_trivially_destructed_temporary(); // expected-warning {{object whose reference is captured does not live long enough}} \ + a = non_trivially_destructed_temporary(); // expected-warning {{local temporary object does not live long enough}} \ expected-note {{destroyed here}} use(a); // expected-note {{later used here}} } void passing_temporary_to_lifetime_bound_function() { - View a = construct_view(non_trivially_destructed_temporary()); // expected-warning {{object whose reference is captured does not live long enough}} \ + View a = construct_view(non_trivially_destructed_temporary()); // expected-warning {{local temporary object does not live long enough}} \ expected-note {{destroyed here}} use(a); // expected-note {{later used here}} } void use_trivial_temporary_after_destruction() { View a; - a = trivially_destructed_temporary(); // expected-warning {{object whose reference is captured does not live long enough}} \ + a = trivially_destructed_temporary(); // expected-warning {{local temporary object does not live long enough}} \ expected-note {{destroyed here}} use(a); // expected-note {{later used here}} } @@ -1324,7 +1324,7 @@ void foobar() { View view; { StatusOr<MyObj> string_or = getStringOr(); - view = string_or. // expected-warning {{object whose reference is captured does not live long enough}} + view = string_or. // expected-warning {{local variable 'string_or' does not live long enough}} value(); } // expected-note {{destroyed here}} (void)view; // expected-note {{later used here}} @@ -1344,7 +1344,7 @@ void range_based_for_use_after_scope() { View v; { MyObjStorage s; - for (const MyObj &o : s) { // expected-warning {{object whose reference is captured does not live long enough}} + for (const MyObj &o : s) { // expected-warning {{local variable 's' does not live long enough}} v = o; } } // expected-note {{destroyed here}} @@ -1365,7 +1365,7 @@ void range_based_for_not_reference() { { MyObjStorage s; for (MyObj o : s) { // expected-note {{destroyed here}} - v = o; // expected-warning {{object whose reference is captured does not live long enough}} + v = o; // expected-warning {{local variable 'o' does not live long enough}} } } v.use(); // expected-note {{later used here}} @@ -1398,7 +1398,7 @@ void test_user_defined_deref_uaf() { { MyObj obj; SmartPtr<MyObj> smart_ptr(&obj); - p = &(*smart_ptr); // expected-warning {{object whose reference is captured does not live long enough}} + p = &(*smart_ptr); // expected-warning {{local variable 'smart_ptr' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -1415,7 +1415,7 @@ void test_user_defined_deref_with_view() { { MyObj obj; SmartPtr<MyObj> smart_ptr(&obj); - v = *smart_ptr; // expected-warning {{object whose reference is captured does not live long enough}} + v = *smart_ptr; // expected-warning {{local variable 'smart_ptr' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -1425,7 +1425,7 @@ void test_user_defined_deref_arrow() { { MyObj obj; SmartPtr<MyObj> smart_ptr(&obj); - p = smart_ptr.operator->(); // expected-warning {{object whose reference is captured does not live long enough}} + p = smart_ptr.operator->(); // expected-warning {{local variable 'smart_ptr' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -1435,7 +1435,7 @@ void test_user_defined_deref_chained() { { MyObj obj; SmartPtr<SmartPtr<MyObj>> double_ptr; - p = &(**double_ptr); // expected-warning {{object whose reference is captured does not live long enough}} + p = &(**double_ptr); // expected-warning {{local variable 'double_ptr' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -1586,7 +1586,7 @@ void strict_warn_on_move() { View v; { MyObj a; - v = a; // expected-warning-re {{object whose reference {{.*}} may have been moved}} + v = a; // expected-warning {{local variable 'a' may not live long enough. This could be a false positive as the storage may have been moved later}} b = std::move(a); // expected-note {{potentially moved here}} } // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} @@ -1600,7 +1600,7 @@ void flow_sensitive(bool c) { MyObj b = std::move(a); return; } - v = a; // expected-warning {{object whose reference}} + v = a; // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} } @@ -1610,7 +1610,8 @@ void detect_conditional(bool cond) { View v; { MyObj a, b; - v = cond ? a : b; // expected-warning-re 2 {{object whose reference {{.*}} may have been moved}} + v = cond ? a : b; // expected-warning {{local variable 'a' may not live long enough. This could be a false positive as the storage may have been moved later}} \ + // expected-warning {{local variable 'b' may not live long enough. This could be a false positive as the storage may have been moved later}} take(std::move(cond ? a : b)); // expected-note 2 {{potentially moved here}} } // expected-note 2 {{destroyed here}} (void)v; // expected-note 2 {{later used here}} @@ -1620,13 +1621,13 @@ void wrong_use_of_move_is_permissive() { View v; { MyObj a; - v = std::move(a); // expected-warning {{object whose reference is captured does not live long enough}} + v = std::move(a); // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)v; // expected-note {{later used here}} const int* p; { MyObj a; - p = std::move(a).getData(); // expected-warning {{object whose reference is captured does not live long enough}} + p = std::move(a).getData(); // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)p; // expected-note {{later used here}} } @@ -1637,7 +1638,7 @@ void test_release_no_uaf() { // Calling release() marks p as moved from, so its destruction doesn't invalidate r. { std::unique_ptr<int> p; - r = p.get(); // expected-warning-re {{object whose reference {{.*}} may have been moved}} + r = p.get(); // expected-warning {{local variable 'p' may not live long enough. This could be a false positive as the storage may have been moved later}} take(p.release()); // expected-note {{potentially moved here}} } // expected-note {{destroyed here}} (void)*r; // expected-note {{later used here}} @@ -1659,8 +1660,8 @@ void bar() { View x; { S s; - x = s.x(); // expected-warning {{object whose reference is captured does not live long enough}} - View y = S().x(); // expected-warning {{object whose reference is captured does not live long enough}} \ + x = s.x(); // expected-warning {{local variable 's' does not live long enough}} + View y = S().x(); // expected-warning {{local temporary object does not live long enough}} \ expected-note {{destroyed here}} (void)y; // expected-note {{used here}} } // expected-note {{destroyed here}} @@ -1749,16 +1750,16 @@ const std::string& identity(const std::string& in [[clang::lifetimebound]]); const S& identity(const S& in [[clang::lifetimebound]]); void test_temporary() { - const std::string& x = S().x(); // expected-warning {{object whose reference is captured does not live long enough}} expected-note {{destroyed here}} + const std::string& x = S().x(); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} (void)x; // expected-note {{later used here}} - const std::string& y = identity(S().x()); // expected-warning {{object whose reference is captured does not live long enough}} expected-note {{destroyed here}} + const std::string& y = identity(S().x()); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} (void)y; // expected-note {{later used here}} std::string_view z; { S s; - const std::string& zz = s.x(); // expected-warning {{object whose reference is captured does not live long enough}} + const std::string& zz = s.x(); // expected-warning {{local variable 's' does not live long enough}} z = zz; } // expected-note {{destroyed here}} (void)z; // expected-note {{later used here}} @@ -1767,12 +1768,12 @@ void test_temporary() { void test_lifetime_extension_ok() { const S& x = S(); (void)x; - const S& y = identity(S()); // expected-warning {{object whose reference is captured does not live long enough}} expected-note {{destroyed here}} + const S& y = identity(S()); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} (void)y; // expected-note {{later used here}} } const std::string& test_return() { - const std::string& x = S().x(); // expected-warning {{object whose reference is captured does not live long enough}} expected-note {{destroyed here}} + const std::string& x = S().x(); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} return x; // expected-note {{later used here}} } } // namespace reference_type_decl_ref_expr @@ -1788,7 +1789,7 @@ void uaf() { std::string_view view; { S str; - S* p = &str; // expected-warning {{object whose reference is captured does not live long enough}} + S* p = &str; // expected-warning {{local variable 'str' does not live long enough}} view = p->s; } // expected-note {{destroyed here}} (void)view; // expected-note {{later used here}} @@ -1814,7 +1815,7 @@ void uaf_union() { std::string_view view; { U u = U{"hello"}; - U* up = &u; // expected-warning {{object whose reference is captured does not live long enough}} + U* up = &u; // expected-warning {{local variable 'u' does not live long enough}} view = up->s; } // expected-note {{destroyed here}} (void)view; // expected-note {{later used here}} @@ -1831,7 +1832,7 @@ void uaf_anonymous_union() { int* ip; { AnonymousUnion au; - AnonymousUnion* up = &au; // expected-warning {{object whose reference is captured does not live long enough}} + AnonymousUnion* up = &au; // expected-warning {{local variable 'au' does not live long enough}} ip = &up->x; } // expected-note {{destroyed here}} (void)ip; // expected-note {{later used here}} @@ -1890,9 +1891,9 @@ const T* MemberFuncsTpl<T>::memberC(const T& x [[clang::lifetimebound]]) { void test() { MemberFuncsTpl<MyObj> mtf; - const MyObj* pTMA = mtf.memberA(MyObj()); // expected-warning {{object whose reference is captured does not live long enough}} // expected-note {{destroyed here}} - const MyObj* pTMB = mtf.memberB(MyObj()); // tu-warning {{object whose reference is captured does not live long enough}} // tu-note {{destroyed here}} - const MyObj* pTMC = mtf.memberC(MyObj()); // expected-warning {{object whose reference is captured does not live long enough}} // expected-note {{destroyed here}} + const MyObj* pTMA = mtf.memberA(MyObj()); // expected-warning {{local temporary object does not live long enough}} // expected-note {{destroyed here}} + const MyObj* pTMB = mtf.memberB(MyObj()); // tu-warning {{local temporary object does not live long enough}} // tu-note {{destroyed here}} + const MyObj* pTMC = mtf.memberC(MyObj()); // expected-warning {{local temporary object does not live long enough}} // expected-note {{destroyed here}} (void)pTMA; // expected-note {{later used here}} (void)pTMB; // tu-note {{later used here}} (void)pTMC; // expected-note {{later used here}} @@ -1927,7 +1928,7 @@ void test_optional_arrow() { const char* p; { std::optional<std::string> opt; - p = opt->data(); // expected-warning {{object whose reference is captured does not live long enough}} + p = opt->data(); // expected-warning {{local variable 'opt' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -1936,7 +1937,7 @@ void test_optional_arrow_lifetimebound() { View v; { std::optional<MyObj> opt; - v = opt->getView(); // expected-warning {{object whose reference is captured does not live long enough}} + v = opt->getView(); // expected-warning {{local variable 'opt' does not live long enough}} } // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -1945,7 +1946,7 @@ void test_unique_ptr_arrow() { const char* p; { std::unique_ptr<std::string> up; - p = up->data(); // expected-warning {{object whose reference is captured does not live long enough}} + p = up->data(); // expected-warning {{local variable 'up' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -2136,7 +2137,7 @@ void multi_level_pointer_in_loop() { MyObj* p; MyObj** pp; if (i > 5) { - p = &obj; // expected-warning {{object whose reference is captured does not live long enough}} + p = &obj; // expected-warning {{local variable 'obj' does not live long enough}} pp = &p; } (void)**pp; // expected-note {{later used here}} @@ -2148,7 +2149,7 @@ void outer_pointer_outlives_inner_pointee() { MyObj* view = &safe; for (int i = 0; i < 10; ++i) { MyObj obj; - view = &obj; // expected-warning {{object whose reference is captured does not live long enough}} + view = &obj; // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)*view; // expected-note {{later used here}} } @@ -2161,7 +2162,7 @@ void element_use_after_scope() { int* p; { int a[10]{}; - p = &a[2]; // expected-warning {{object whose reference is captured does not live long enough}} + p = &a[2]; // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -2193,7 +2194,7 @@ void multidimensional_use_after_scope() { int* p; { int a[3][4]{}; - p = &a[1][2]; // expected-warning {{object whose reference is captured does not live long enough}} + p = &a[1][2]; // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -2206,7 +2207,7 @@ void member_array_element_use_after_scope() { int* p; { S s; - p = &s.arr[0]; // expected-warning {{object whose reference is captured does not live long enough}} + p = &s.arr[0]; // expected-warning {{local variable 's' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -2215,7 +2216,7 @@ void array_of_pointers_use_after_scope() { int** p; { int* a[10]{}; - p = a; // expected-warning {{object whose reference is captured does not live long enough}} + p = a; // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -2224,7 +2225,7 @@ void reversed_subscript_use_after_scope() { int* p; { int a[10]{}; - p = &(0[a]); // expected-warning {{object whose reference is captured does not live long enough}} + p = &(0[a]); // expected-warning {{local variable 'a' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -2250,9 +2251,9 @@ void pointer_arithmetic_use_after_scope() { int* p3; { int a[10]{}; - p = a + 5; // expected-warning {{object whose reference is captured does not live long enough}} - p2 = a - 5; // expected-warning {{object whose reference is captured does not live long enough}} - p3 = 5 + a; // expected-warning {{object whose reference is captured does not live long enough}} + p = a + 5; // expected-warning {{local variable 'a' does not live long enough}} + p2 = a - 5; // expected-warning {{local variable 'a' does not live long enough}} + p3 = 5 + a; // expected-warning {{local variable 'a' does not live long enough}} } // expected-note 3 {{destroyed here}} (void)*p; // expected-note {{later used here}} (void)*p2; // expected-note {{later used here}} @@ -2298,8 +2299,8 @@ struct S { void indexing_with_static_operator() { S()(1, 2); S& x = S()("1", - 2, // expected-warning {{object whose reference is captured does not live long enough}} expected-note {{destroyed here}} - 3); // expected-warning {{object whose reference is captured does not live long enough}} expected-note {{destroyed here}} + 2, // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} + 3); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} (void)x; // expected-note 2 {{later used here}} @@ -2321,13 +2322,13 @@ struct S { S getS(const std::string &s [[clang::lifetimebound]]); void from_free_function() { - S s = getS(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + S s = getS(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } void from_constructor() { - S s(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + S s(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } @@ -2340,13 +2341,13 @@ struct Factory { void from_method() { Factory f; - S s = f.make(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + S s = f.make(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } void from_static_method() { - S s = Factory::create(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + S s = Factory::create(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } @@ -2355,7 +2356,7 @@ void from_lifetimebound_this_method() { S value; { Factory f; - value = f.makeThis(); // expected-warning {{object whose reference is captured does not live long enough}} + value = f.makeThis(); // expected-warning {{local variable 'f' does not live long enough}} } // expected-note {{destroyed here}} use(value); // expected-note {{later used here}} } @@ -2364,7 +2365,7 @@ void across_scope() { S s{}; { std::string str{"abc"}; - s = getS(str); // expected-warning {{object whose reference is captured does not live long enough}} + s = getS(str); // expected-warning {{local variable 'str' does not live long enough}} } // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } @@ -2386,7 +2387,7 @@ void assignment_propagation() { S a, b; { std::string str{"abc"}; - a = getS(str); // expected-warning {{object whose reference is captured does not live long enough}} + a = getS(str); // expected-warning {{local variable 'str' does not live long enough}} b = a; } // expected-note {{destroyed here}} use(b); // expected-note {{later used here}} @@ -2396,7 +2397,7 @@ void chained_defaulted_assignment_propagation() { S b, c; { std::string str{"abc"}; - S a = getS(str); // expected-warning {{object whose reference is captured does not live long enough}} + S a = getS(str); // expected-warning {{local variable 'str' does not live long enough}} c = b = a; } // expected-note {{destroyed here}} use(c); // expected-note {{later used here}} @@ -2410,7 +2411,7 @@ void no_annotation() { } void mix_annotated_and_not() { - S s1 = getS(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + S s1 = getS(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} S s2 = getSNoAnnotation(std::string("temp")); use(s1); // expected-note {{later used here}} @@ -2422,7 +2423,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 {{stack memory associated with local variable 'str' is returned}} \ - // expected-warning {{object whose reference is captured does not live long enough}} \ + // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} return s; // expected-note {{returned here}} \ // expected-note {{later used here}} @@ -2441,7 +2442,7 @@ template <class T> T make(const std::string &s [[clang::lifetimebound]]); void from_template_instantiation() { - S s = make<S>(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + S s = make<S>(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } @@ -2504,7 +2505,7 @@ using SAlias = S; SAlias getSAlias(const std::string &s [[clang::lifetimebound]]); void from_typedef_return() { - SAlias s = getSAlias(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + SAlias s = getSAlias(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } @@ -2578,7 +2579,7 @@ std::span<std::string_view> owner_to_pointer_via_gsl_construction() { std::unique_ptr<S> getUniqueS(const std::string &s [[clang::lifetimebound]]); void owner_return_unique_ptr_s() { - auto ptr = getUniqueS(std::string("temp")); // expected-warning {{object whose reference is captured does not live long enough}} \ + auto ptr = getUniqueS(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} (void)ptr; // expected-note {{later used here}} } @@ -2595,7 +2596,7 @@ void owner_outlives_lifetimebound_source() { std::unique_ptr<S> ups; { std::string local; - ups = getUniqueS(local); // expected-warning {{object whose reference is captured does not live long enough}} + ups = getUniqueS(local); // expected-warning {{local variable 'local' does not live long enough}} } // expected-note {{destroyed here}} (void)ups; // expected-note {{later used here}} } @@ -2618,7 +2619,7 @@ void local_pointer() { Pointer<int> p; { int v; - p = Pointer(v); // expected-warning {{object whose reference is captured does not live long enough}} + p = Pointer(v); // expected-warning {{local variable 'v' does not live long enough}} } // expected-note {{destroyed here}} use(*p); // expected-note {{later used here}} } @@ -2629,7 +2630,7 @@ void nested_local_pointer() { Pointer<Bar> p; { Bar v; - p = Pointer(v); // expected-warning {{object whose reference is captured does not live long enough}} + p = Pointer(v); // expected-warning {{local variable 'v' does not live long enough}} pp = Pointer(p); ppp = Pointer(pp); } // expected-note {{destroyed here}} @@ -2712,7 +2713,7 @@ void new_view_from_dead_scope() { View *p; { MyObj obj; - p = new View(obj); // expected-warning {{object whose reference is captured does not live long enough}} + p = new View(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} p->use(); // expected-note {{later used here}} } @@ -2757,7 +2758,7 @@ void new_pointer_from_pointer() { MyObj **p; { MyObj obj; - MyObj *q = &obj; // expected-warning {{object whose reference is captured does not live long enough}} + MyObj *q = &obj; // expected-warning {{local variable 'obj' does not live long enough}} p = new MyObj *(q); } // expected-note {{destroyed here}} (void)**p; // expected-note {{later used here}} @@ -2767,7 +2768,7 @@ void new_pointer_from_dead_object() { MyObj **p; { MyObj obj; - p = new MyObj *(&obj); // expected-warning {{object whose reference is captured does not live long enough}} + p = new MyObj *(&obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)**p; // expected-note {{later used here}} } @@ -2781,7 +2782,7 @@ void new_multiview_from_mixed_scope() { MultiView *p; { MyObj obj2; - p = new MultiView(obj1, obj2); // expected-warning {{object whose reference is captured does not live long enough}} + p = new MultiView(obj1, obj2); // expected-warning {{local variable 'obj2' does not live long enough}} } // expected-note {{destroyed here}} (void)p; // expected-note {{later used here}} } @@ -2932,7 +2933,7 @@ void placement_new_int_basic() { int *p; { int storage; - p = new (&storage) int; // expected-warning {{object whose reference is captured does not live long enough}} + p = new (&storage) int; // expected-warning {{local variable 'storage' does not live long enough}} } // expected-note {{destroyed here}} (void)*p; // expected-note {{later used here}} } @@ -2942,7 +2943,7 @@ void placement_new_view_from_dead_scope() { View *p = &storage; { MyObj obj; - p = new (&storage) View(obj); // expected-warning {{object whose reference is captured does not live long enough}} + p = new (&storage) View(obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} p->use(); // expected-note {{later used here}} } @@ -2952,7 +2953,7 @@ void placement_new_pointer_from_dead_object() { MyObj **p = &slot; { MyObj obj; - p = new (&slot) MyObj *(&obj); // expected-warning {{object whose reference is captured does not live long enough}} + p = new (&slot) MyObj *(&obj); // expected-warning {{local variable 'obj' does not live long enough}} } // expected-note {{destroyed here}} (void)**p; // expected-note {{later used here}} } @@ -2961,7 +2962,7 @@ void placement_new_array_basic() { int *p; { int storage[2]; - p = new (&storage) int[2]; // expected-warning {{object whose reference is captured does not live long enough}} + p = new (&storage) int[2]; // expected-warning {{local variable 'storage' does not live long enough}} } // expected-note {{destroyed here}} (void)p[0]; // expected-note {{later used here}} } @@ -2970,7 +2971,7 @@ void placement_new_array_braces() { int *p; { int storage[2]; - p = new (&storage) int[2]{}; // expected-warning {{object whose reference is captured does not live long enough}} + p = new (&storage) int[2]{}; // expected-warning {{local variable 'storage' does not live long enough}} } // expected-note {{destroyed here}} (void)p[0]; // expected-note {{later used here}} } @@ -3139,7 +3140,7 @@ struct S { void foo() { { int num; - this->p_ = # // expected-warning {{object whose reference is captured does not live long enough}} + this->p_ = # // expected-warning {{local variable 'num' does not live long enough}} } // expected-note {{destroyed here}} bar(); // expected-note {{later used here}} this->p_ = &GLOBAL_INT; @@ -3158,7 +3159,7 @@ struct T { std::string_view v; void bar(); void foo() { - v = std::string("tmp"); // expected-warning {{object whose reference is captured does not live long enough}} expected-note {{destroyed here}} + v = std::string("tmp"); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} bar(); // expected-note {{later used here}} } }; @@ -3179,7 +3180,7 @@ struct S2 : S { void foo2() { { int num; - this->p_ = # // expected-warning {{object whose reference is captured does not live long enough}} + this->p_ = # // expected-warning {{local variable 'num' does not live long enough}} } // expected-note {{destroyed here}} bar(); // expected-note {{later used here}} this->p_ = &GLOBAL_INT; @@ -3187,7 +3188,7 @@ struct S2 : S { void baz2() { { int num; - this->p_ = # // expected-warning {{object whose reference is captured does not live long enough}} + this->p_ = # // expected-warning {{local variable 'num' does not live long enough}} } // expected-note {{destroyed here}} bar2(); // expected-note {{later used here}} this->p_ = nullptr; @@ -3307,7 +3308,7 @@ void uaf_via_lifetimebound() { std::function<void()> f = []() {}; { int local; - f = capture_lifetimebound_param(local); // expected-warning {{object whose reference is captured does not live long enough}} + f = capture_lifetimebound_param(local); // expected-warning {{local variable 'local' does not live long enough}} } // expected-note {{destroyed here}} (void)f; // expected-note {{later used here}} } @@ -3326,7 +3327,7 @@ struct [[gsl::Pointer]] function_ref { // lifetimebound(2) could enable tracking inner lifetimes, which would // avoid this warning for non-capturing lambdas. void assign_non_capturing_to_function_ref(function_ref &r) { - r = []() {}; // expected-warning {{object whose reference is captured does not live long enough}} \ + r = []() {}; // expected-warning {{local temporary object does not live long enough}} \ // expected-note {{destroyed here}} (void)r; // expected-note {{later used here}} } @@ -3370,7 +3371,7 @@ void deref_use_after_scope() { const MyObj* p; { optional<MyObj> opt; - p = &*opt; // expected-warning {{object whose reference is captured does not live long enough}} + p = &*opt; // expected-warning {{local variable 'opt' does not live long enough}} } // expected-note {{destroyed here}} (void)p->id; // expected-note {{later used here}} } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
