[clang] [LifetimeSafety] Change "local temporary object" to "temporary object" in diagnostics (PR #203573)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 12 09:07:34 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Utkarsh Saxena (usx95)
<details>
<summary>Changes</summary>
---
Patch is 59.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/203573.diff
4 Files Affected:
- (modified) clang/lib/Sema/SemaLifetimeSafety.h (+1-1)
- (modified) clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp (+8-8)
- (modified) clang/test/Sema/LifetimeSafety/nocfg.cpp (+93-93)
- (modified) clang/test/Sema/LifetimeSafety/safety.cpp (+51-51)
``````````diff
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 at -1 {{destroyed here}}
- // expected-note at -2 {{expression aliases the storage of local temporary object}}
+ // expected-note at -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 at -1 {{destroyed here}}
- // expected-note at -2 {{expression aliases the storage of local temporary object}}
+ // expected-note at -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 at -1 {{destroyed here}}
- // expected-note at -2 {{expression aliases the storage of local temporary object}}
+ // expected-note at -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}} \
- ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/203573
More information about the cfe-commits
mailing list