https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/203573
None >From 7781cdf4bc27943aa7fe275d2e729017d42976a7 Mon Sep 17 00:00:00 2001 From: Utkarsh Saxena <[email protected]> Date: Fri, 12 Jun 2026 15:59:17 +0000 Subject: [PATCH] rename temporary object --- clang/lib/Sema/SemaLifetimeSafety.h | 2 +- .../LifetimeSafety/annotation-suggestions.cpp | 16 +- clang/test/Sema/LifetimeSafety/nocfg.cpp | 186 +++++++++--------- clang/test/Sema/LifetimeSafety/safety.cpp | 102 +++++----- 4 files changed, 153 insertions(+), 153 deletions(-) diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h index a7c628f315d78..565c30f74cf9a 100644 --- a/clang/lib/Sema/SemaLifetimeSafety.h +++ b/clang/lib/Sema/SemaLifetimeSafety.h @@ -486,7 +486,7 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper { std::string getDiagSubjectDescription(const Expr *E) { E = E->IgnoreImpCasts(); if (isa<MaterializeTemporaryExpr>(E)) - return "local temporary object"; + return "temporary object"; if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) return getDiagSubjectDescription(DRE->getDecl()); diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp index 1f94e101fb9ef..6abdc32c2d743 100644 --- a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp +++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp @@ -276,23 +276,23 @@ View return_view_field(const ViewProvider& v) { // expected-warning {{paramet } void test_get_on_temporary_pointer() { - const ReturnsSelf* s_ref = &ReturnsSelf().get(); // expected-warning {{local temporary object does not live long enough}}. + const ReturnsSelf* s_ref = &ReturnsSelf().get(); // expected-warning {{temporary object does not live long enough}}. // expected-note@-1 {{destroyed here}} - // expected-note@-2 {{expression aliases the storage of local temporary object}} + // expected-note@-2 {{expression aliases the storage of temporary object}} (void)s_ref; // expected-note {{later used here}} } void test_get_on_temporary_ref() { - const ReturnsSelf& s_ref = ReturnsSelf().get(); // expected-warning {{local temporary object does not live long enough}}. + const ReturnsSelf& s_ref = ReturnsSelf().get(); // expected-warning {{temporary object does not live long enough}}. // expected-note@-1 {{destroyed here}} - // expected-note@-2 {{expression aliases the storage of local temporary object}} + // expected-note@-2 {{expression aliases the storage of temporary object}} (void)s_ref; // expected-note {{later used here}} } void test_getView_on_temporary() { - View sv = ViewProvider{1}.getView(); // expected-warning {{local temporary object does not live long enough}}. + View sv = ViewProvider{1}.getView(); // expected-warning {{temporary object does not live long enough}}. // expected-note@-1 {{destroyed here}} - // expected-note@-2 {{expression aliases the storage of local temporary object}} + // expected-note@-2 {{expression aliases the storage of temporary object}} (void)sv; // expected-note {{later used here}} } @@ -640,9 +640,9 @@ View* MakeView(const MyObj& in) { // expected-warning {{parameter in intra-TU fu } void test_new_allocation() { - View* v = MakeView(MyObj{}); // expected-warning {{local temporary object does not live long enough}} \ + View* v = MakeView(MyObj{}); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} (void)v; // expected-note {{later used here}} } diff --git a/clang/test/Sema/LifetimeSafety/nocfg.cpp b/clang/test/Sema/LifetimeSafety/nocfg.cpp index 49b6175d378ae..3d7d59086ea54 100644 --- a/clang/test/Sema/LifetimeSafety/nocfg.cpp +++ b/clang/test/Sema/LifetimeSafety/nocfg.cpp @@ -75,7 +75,7 @@ struct Y { }; void dangligGslPtrFromTemporary() { - MyIntPointer p = Y{}.a; // cfg-warning {{local temporary object does not live long enough}} \ + MyIntPointer p = Y{}.a; // cfg-warning {{temporary object does not live long enough}} \ // cfg-note {{destroyed here}} (void)p; // cfg-note {{later used here}} } @@ -88,9 +88,9 @@ struct DanglingGslPtrField { DanglingGslPtrField(int i) : p(&i) {} // cfg-warning {{stack memory associated with parameter 'i' escapes to the field 'p' which will dangle}} DanglingGslPtrField() : p2(MyLongOwnerWithConversion{}) {} // expected-warning {{initializing pointer member 'p2' to point to a temporary object whose lifetime is shorter than the lifetime of the constructed object}} \ - // cfg-warning {{stack memory associated with local temporary object escapes to the field 'p2' which will dangle}} + // cfg-warning {{stack memory associated with temporary object escapes to the field 'p2' which will dangle}} DanglingGslPtrField(double) : p(MyIntOwner{}) {} // expected-warning {{initializing pointer member 'p' to point to a temporary object whose lifetime is shorter than the lifetime of the constructed object}} \ - // cfg-warning {{stack memory associated with local temporary object escapes to the field 'p' which will dangle}} + // cfg-warning {{stack memory associated with temporary object escapes to the field 'p' which will dangle}} DanglingGslPtrField(MyIntOwner io) : p(io) {} // cfg-warning {{stack memory associated with parameter 'io' escapes to the field 'p' which will dangle}} DanglingGslPtrField(MyLongOwnerWithConversion lo) : p2(lo) {} // cfg-warning {{stack memory associated with parameter 'lo' escapes to the field 'p2' which will dangle}} }; @@ -120,19 +120,19 @@ MyLongPointerFromConversion daglingGslPtrFromLocalOwnerConv() { MyIntPointer danglingGslPtrFromTemporary() { return MyIntOwner{}; // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } MyIntOwner makeTempOwner(); MyIntPointer danglingGslPtrFromTemporary2() { return makeTempOwner(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } MyLongPointerFromConversion danglingGslPtrFromTemporaryConv() { return MyLongOwnerWithConversion{}; // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } int *noFalsePositive(MyIntOwner &o) { @@ -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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} global2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer 'global2' }} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} use(global2, p2); // cfg-note 2 {{later used here}} } @@ -180,7 +180,7 @@ struct LifetimeBoundCtor { }; auto lifetimebound_make_unique_single_param() { - return std::make_unique<LifetimeBoundCtor>(MyIntOwner{}); // tu-warning {{stack memory associated with local temporary object is returned}} tu-note {{returned here}} + return std::make_unique<LifetimeBoundCtor>(MyIntOwner{}); // tu-warning {{stack memory associated with temporary object is returned}} tu-note {{returned here}} } @@ -193,24 +193,24 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} (void)it; // cfg-note {{later used here}} } std::vector<int>::iterator modelIteratorReturn() { return std::vector<int>().begin(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } int modelAnyCast2() { @@ -242,13 +242,13 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(c1); // cfg-note {{later used here}} c1 = std::vector<std::string>().at(0); // expected-warning {{object backing the pointer}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(c1); // cfg-note {{later used here}} // no warning on constructing from gsl-pointer @@ -280,58 +280,58 @@ std::string_view localOptional(int i) { const char *danglingRawPtrFromTemp() { return std::basic_string<char>().c_str(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with 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 {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} // 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} // 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(sv); // cfg-note {{later used here}} } @@ -342,8 +342,8 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} cfg-note {{later used here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} cfg-note {{later used here}} \ + // cfg-note {{expression aliases the storage of temporary object}} ; } @@ -363,7 +363,7 @@ int &doNotFollowReferencesForLocalOwner() { const char *trackThroughMultiplePointer() { return std::basic_string_view<char>(std::basic_string<char>()).begin(); // expected-warning {{returning address of local temporary object}} \ - // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } struct X { @@ -405,18 +405,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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} use(a2); // cfg-note {{later used here}} } @@ -461,7 +461,7 @@ std::string_view test_str_local() { v.end(), "42"); } std::string_view test_str_temporary() { - return *std::find(GetTemporaryString().begin(), // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + return *std::find(GetTemporaryString().begin(), // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} GetTemporaryString().end(), "42"); } std::string_view test_view() { @@ -611,7 +611,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 {{local temporary object does not live long enough}} \ + // cfg-warning {{temporary object does not live long enough}} \ // cfg-note {{destroyed here}} use(url); // cfg-note {{later used here}} } @@ -620,8 +620,8 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(svjkk1); // cfg-note {{later used here}} } } // namespace GH100549 @@ -855,8 +855,8 @@ namespace GH118064{ void test() { auto y = std::set<int>{}.begin(); // expected-warning {{object backing the pointer}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(y); // cfg-note {{later used here}} } } // namespace GH118064 @@ -871,42 +871,42 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(t1); // cfg-note {{later used here}} t1 = Ref(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} 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}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } std::string_view test1_2() { std::string_view t2 = TakeSv(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(t2); // cfg-note {{later used here}} t2 = TakeSv(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(t2); // cfg-note {{later used here}} return TakeSv(std::string()); // expected-warning {{returning address}} \ - // cfg-warning {{stack memory associated with local temporary object is returned}} cfg-note {{returned here}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } std::string_view test1_3() { std::string_view t3 = TakeStrRef(std::string()); // expected-warning {{temporary}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(t3); // cfg-note {{later used here}} t3 = TakeStrRef(std::string()); // expected-warning {{object backing}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} 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}} + // cfg-warning {{stack memory associated with temporary object is returned}} cfg-note {{returned here}} } std::string_view test1_4() { @@ -925,12 +925,12 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} use(t1); // cfg-note {{later used here}} t1 = Foo<std::string>().get(); // expected-warning {{object backing}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} 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}} @@ -959,9 +959,9 @@ struct [[gsl::Pointer]] Pointer { Pointer(const Bar & bar [[clang::lifetimebound]]); }; Pointer test3(Bar bar) { - Pointer p = Pointer(Bar()); // expected-warning {{temporary}} cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + Pointer p = Pointer(Bar()); // expected-warning {{temporary}} cfg-warning {{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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} + p = Pointer(Bar()); // expected-warning {{object backing}} cfg-warning {{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}} } @@ -1048,12 +1048,12 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 3 {{expression aliases the storage of local temporary object}} - const char* y = (*temporary().begin()).data(); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 3 {{expression aliases the storage of local temporary object}} - const std::string& z = (*temporary().begin()); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 2 {{expression aliases the storage of local temporary object}} + const char* x = temporary().begin()->data(); // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 3 {{expression aliases the storage of temporary object}} + const char* y = (*temporary().begin()).data(); // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 3 {{expression aliases the storage of temporary object}} + const std::string& z = (*temporary().begin()); // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 2 {{expression aliases the storage of temporary object}} use(p, q, r, x, y, z); // cfg-note 3 {{later used here}} } @@ -1065,12 +1065,12 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 3 {{expression aliases the storage of local temporary object}} - const char* y = (*temporary().begin()).second.data(); // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 3 {{expression aliases the storage of local temporary object}} - const std::string& z = (*temporary().begin()).second; // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 2 {{expression aliases the storage of local temporary object}} + const char* x = temporary().begin()->second.data(); // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 3 {{expression aliases the storage of temporary object}} + const char* y = (*temporary().begin()).second.data(); // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 3 {{expression aliases the storage of temporary object}} + const std::string& z = (*temporary().begin()).second; // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 2 {{expression aliases the storage of temporary object}} use(p, q, r, x, y, z); // cfg-note 3 {{later used here}} } @@ -1120,21 +1120,21 @@ 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 {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note {{expression aliases the storage of temporary object}} std::string_view k3 = Q().get()->sv; // OK std::string_view k4 = Q().get()->s; // expected-warning {{object backing the pointer will}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 2 {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 2 {{expression aliases the storage of temporary object}} std::string_view lb1 = foo(S().s); // expected-warning {{object backing the pointer will}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 2 {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 2 {{expression aliases the storage of temporary object}} std::string_view lb2 = foo(Q().get()->s); // expected-warning {{object backing the pointer will}} \ - // cfg-warning {{local temporary object does not live long enough}} cfg-note {{destroyed here}} \ - // cfg-note 3 {{expression aliases the storage of local temporary object}} + // cfg-warning {{temporary object does not live long enough}} cfg-note {{destroyed here}} \ + // cfg-note 3 {{expression aliases the storage of temporary object}} use(k1, k2, k3, k4, lb1, lb2); // cfg-note 4 {{later used here}} } diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp b/clang/test/Sema/LifetimeSafety/safety.cpp index 2aa5ff43ec3bc..d976baa545b8c 100644 --- a/clang/test/Sema/LifetimeSafety/safety.cpp +++ b/clang/test/Sema/LifetimeSafety/safety.cpp @@ -1025,9 +1025,9 @@ void non_lifetimebound_make_unique() { } void lifetimebound_make_unique_temp() { - std::unique_ptr<LifetimeBoundCtor> ptr = std::make_unique<LifetimeBoundCtor>(MyObj()); // tu-warning {{local temporary object does not live long enough}} \ + std::unique_ptr<LifetimeBoundCtor> ptr = std::make_unique<LifetimeBoundCtor>(MyObj()); // tu-warning {{temporary object does not live long enough}} \ // tu-note {{destroyed here}} \ - // tu-note {{expression aliases the storage of local temporary object}} + // tu-note {{expression aliases the storage of temporary object}} (void)ptr; // tu-note {{later used here}} } @@ -1285,37 +1285,37 @@ void parentheses(bool cond) { void use_temporary_after_destruction() { View a; - a = non_trivially_destructed_temporary(); // expected-warning {{local temporary object does not live long enough}} \ + a = non_trivially_destructed_temporary(); // expected-warning {{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 {{local temporary object does not live long enough}} \ + View a = construct_view(non_trivially_destructed_temporary()); // expected-warning {{temporary object does not live long enough}} \ expected-note {{destroyed here}} \ - expected-note {{expression aliases the storage of local temporary object}} + expected-note {{expression aliases the storage of temporary object}} use(a); // expected-note {{later used here}} } void use_trivial_temporary_after_destruction() { View a; - a = trivially_destructed_temporary(); // expected-warning {{local temporary object does not live long enough}} \ + a = trivially_destructed_temporary(); // expected-warning {{temporary object does not live long enough}} \ expected-note {{destroyed here}} use(a); // expected-note {{later used here}} } namespace FullExprCleanupLoc { void var_initializer() { - View v = non_trivially_destructed_temporary() // expected-warning {{local temporary object does not live long enough}} \ - // expected-note {{expression aliases the storage of local temporary object}} + View v = non_trivially_destructed_temporary() // expected-warning {{temporary object does not live long enough}} \ + // expected-note {{expression aliases the storage of temporary object}} .getView(); // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } void expr_statement() { View v; - v = non_trivially_destructed_temporary() // expected-warning {{local temporary object does not live long enough}} \ - // expected-note {{expression aliases the storage of local temporary object}} + v = non_trivially_destructed_temporary() // expected-warning {{temporary object does not live long enough}} \ + // expected-note {{expression aliases the storage of temporary object}} .getView(); // expected-note {{destroyed here}} v.use(); // expected-note {{later used here}} } @@ -1704,9 +1704,9 @@ void bar() { S s; x = s.x(); // expected-warning {{local variable 's' does not live long enough}} \ // expected-note {{expression aliases the storage of local variable 's'}} - View y = S().x(); // expected-warning {{local temporary object does not live long enough}} \ + View y = S().x(); // expected-warning {{temporary object does not live long enough}} \ expected-note {{destroyed here}} \ - expected-note {{expression aliases the storage of local temporary object}} + expected-note {{expression aliases the storage of temporary object}} (void)y; // expected-note {{used here}} } // expected-note {{destroyed here}} (void)x; // expected-note {{used here}} @@ -1794,12 +1794,12 @@ 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 {{local temporary object does not live long enough}} expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + const std::string& x = S().x(); // expected-warning {{temporary object does not live long enough}} expected-note {{destroyed here}} \ + // expected-note {{expression aliases the storage of temporary object}} (void)x; // expected-note {{later used here}} - const std::string& y = identity(S().x()); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} \ - // expected-note 2 {{expression aliases the storage of local temporary object}} + const std::string& y = identity(S().x()); // expected-warning {{temporary object does not live long enough}} expected-note {{destroyed here}} \ + // expected-note 2 {{expression aliases the storage of temporary object}} (void)y; // expected-note {{later used here}} std::string_view z; @@ -1815,14 +1815,14 @@ void test_temporary() { void test_lifetime_extension_ok() { const S& x = S(); (void)x; - const S& y = identity(S()); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + const S& y = identity(S()); // expected-warning {{temporary object does not live long enough}} expected-note {{destroyed here}} \ + // expected-note {{expression aliases the storage of temporary object}} (void)y; // expected-note {{later used here}} } const std::string& test_return() { - const std::string& x = S().x(); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + const std::string& x = S().x(); // expected-warning {{temporary object does not live long enough}} expected-note {{destroyed here}} \ + // expected-note {{expression aliases the storage of temporary object}} return x; // expected-note {{later used here}} } } // namespace reference_type_decl_ref_expr @@ -1942,12 +1942,12 @@ const T* MemberFuncsTpl<T>::memberC(const T& x [[clang::lifetimebound]]) { void test() { MemberFuncsTpl<MyObj> mtf; - const MyObj* pTMA = mtf.memberA(MyObj()); // expected-warning {{local temporary object does not live long enough}} // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} - const MyObj* pTMB = mtf.memberB(MyObj()); // tu-warning {{local temporary object does not live long enough}} // tu-note {{destroyed here}} \ - // tu-note {{expression aliases the storage of local temporary object}} - const MyObj* pTMC = mtf.memberC(MyObj()); // expected-warning {{local temporary object does not live long enough}} // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + const MyObj* pTMA = mtf.memberA(MyObj()); // expected-warning {{temporary object does not live long enough}} // expected-note {{destroyed here}} \ + // expected-note {{expression aliases the storage of temporary object}} + const MyObj* pTMB = mtf.memberB(MyObj()); // tu-warning {{temporary object does not live long enough}} // tu-note {{destroyed here}} \ + // tu-note {{expression aliases the storage of temporary object}} + const MyObj* pTMC = mtf.memberC(MyObj()); // expected-warning {{temporary object does not live long enough}} // expected-note {{destroyed here}} \ + // expected-note {{expression aliases the storage of temporary object}} (void)pTMA; // expected-note {{later used here}} (void)pTMB; // tu-note {{later used here}} (void)pTMC; // expected-note {{later used here}} @@ -2355,9 +2355,9 @@ struct S { void indexing_with_static_operator() { S()(1, 2); - S& x = S()("1", // expected-note 2 {{expression aliases the storage of local temporary object}} - 2, // expected-warning {{local temporary object does not live long enough}} - 3); // expected-warning {{local temporary object does not live long enough}} expected-note 2 {{destroyed here}} + S& x = S()("1", // expected-note 2 {{expression aliases the storage of temporary object}} + 2, // expected-warning {{temporary object does not live long enough}} + 3); // expected-warning {{temporary object does not live long enough}} expected-note 2 {{destroyed here}} (void)x; // expected-note 2 {{later used here}} @@ -2379,14 +2379,14 @@ struct S { S getS(const std::string &s [[clang::lifetimebound]]); void from_free_function() { - S s = getS(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ + S s = getS(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} use(s); // expected-note {{later used here}} } void from_constructor() { - S s(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ + S s(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} use(s); // expected-note {{later used here}} } @@ -2399,16 +2399,16 @@ struct Factory { void from_method() { Factory f; - S s = f.make(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ + S s = f.make(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} use(s); // expected-note {{later used here}} } void from_static_method() { - S s = Factory::create(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ + S s = Factory::create(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} use(s); // expected-note {{later used here}} } @@ -2476,9 +2476,9 @@ void no_annotation() { } void mix_annotated_and_not() { - S s1 = getS(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ + S s1 = getS(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} S s2 = getSNoAnnotation(std::string("temp")); use(s1); // expected-note {{later used here}} use(s2); @@ -2489,8 +2489,8 @@ 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 {{local temporary object does not live long enough}} \ - // expected-note {{expression aliases the storage of local temporary object}} \ + // expected-warning {{temporary object does not live long enough}} \ + // expected-note {{expression aliases the storage of temporary object}} \ // expected-note {{destroyed here}} return s; // expected-note {{returned here}} \ // expected-note {{later used here}} @@ -2509,15 +2509,15 @@ template <class T> T make(const std::string &s [[clang::lifetimebound]]); void from_template_instantiation() { - S s = make<S>(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ + S s = make<S>(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} use(s); // expected-note {{later used here}} } struct FieldInitFromLifetimebound { S value; // expected-note {{this field dangles}} - FieldInitFromLifetimebound() : value(getS(std::string("temp"))) {} // expected-warning {{stack memory associated with local temporary object escapes to the field 'value' which will dangle}} + FieldInitFromLifetimebound() : value(getS(std::string("temp"))) {} // expected-warning {{stack memory associated with temporary object escapes to the field 'value' which will dangle}} }; S S::return_self_after_registration() const { @@ -2573,9 +2573,9 @@ using SAlias = S; SAlias getSAlias(const std::string &s [[clang::lifetimebound]]); void from_typedef_return() { - SAlias s = getSAlias(std::string("temp")); // expected-warning {{local temporary object does not live long enough}} \ + SAlias s = getSAlias(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} use(s); // expected-note {{later used here}} } @@ -2648,9 +2648,9 @@ 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 {{local temporary object does not live long enough}} \ + auto ptr = getUniqueS(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} \ - // expected-note {{expression aliases the storage of local temporary object}} + // expected-note {{expression aliases the storage of temporary object}} (void)ptr; // expected-note {{later used here}} } @@ -2715,7 +2715,7 @@ struct PFieldFromParam { struct PFieldFromTemp { Pointer<Bar> value; // expected-note {{this field dangles}} - PFieldFromTemp() : value(Bar{}) {} // expected-warning {{stack memory associated with local temporary object escapes to the field 'value' which will dangle}} + PFieldFromTemp() : value(Bar{}) {} // expected-warning {{stack memory associated with temporary object escapes to the field 'value' which will dangle}} }; } // namespace gslpointer_construction_from_lifetimebound @@ -3297,7 +3297,7 @@ struct T { std::string_view v; void bar(); void foo() { - v = std::string("tmp"); // expected-warning {{local temporary object does not live long enough}} expected-note {{destroyed here}} + v = std::string("tmp"); // expected-warning {{temporary object does not live long enough}} expected-note {{destroyed here}} bar(); // expected-note {{later used here}} } }; @@ -3337,7 +3337,7 @@ struct S2 : S { namespace CXXDefaultInitExprTests { struct Holder { - std::string_view view = std::string("temporary"); // expected-warning {{stack memory associated with local temporary object escapes to the field 'view' which will dangle}} expected-note {{this field dangles}} + std::string_view view = std::string("temporary"); // expected-warning {{stack memory associated with temporary object escapes to the field 'view' which will dangle}} expected-note {{this field dangles}} Holder() {} }; } // namespace CXXDefaultInitExprTests @@ -3463,7 +3463,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 {{local temporary object does not live long enough}} \ + r = []() {}; // expected-warning {{temporary object does not live long enough}} \ // expected-note {{destroyed here}} (void)r; // expected-note {{later used here}} } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
