[clang] 4057dfd - [LifetimeSafety] Improve destroyed and invalidated diagnostic notes (#204900)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 23 02:11:05 PDT 2026
Author: PushkarSingh
Date: 2026-06-23T11:11:00+02:00
New Revision: 4057dfd091241ab4784d1355422892b48810edf6
URL: https://github.com/llvm/llvm-project/commit/4057dfd091241ab4784d1355422892b48810edf6
DIFF: https://github.com/llvm/llvm-project/commit/4057dfd091241ab4784d1355422892b48810edf6.diff
LOG: [LifetimeSafety] Improve destroyed and invalidated diagnostic notes (#204900)
## Summary
Improve Lifetime Safety diagnostic notes by identifying the affected
storage in destruction and invalidation notes.
Examples:
```
{
int value;
ptr = &value;
}
```
Before:
```
note: destroyed here
```
After:
```
note: local variable 'value' is destroyed here
```
For temporaries:
```
note: temporary object is destroyed here
```
For invalidations:
```
note: local variable 'container' is invalidated here
```
For parameters:
```
note: parameter 'container' is invalidated here
```
For explicitly deallocated storage:
```
note: allocated object is freed here
```
## Implementation
The lifetime analysis already knows which object is responsible for a
warning. This change reuses that information when producing the
accompanying destruction, invalidation or deallocation note.
All affected regression tests have been updated to check the complete
diagnostic messages.
Addresses #200234
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaLifetimeSafety.h
clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
clang/test/Sema/LifetimeSafety/invalidations.cpp
clang/test/Sema/LifetimeSafety/safety-c.c
clang/test/Sema/LifetimeSafety/safety.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index cb5f124c609ce..cde99dfb16ec5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11056,9 +11056,9 @@ def warn_lifetime_safety_inapplicable_lifetimebound
DefaultIgnore;
def note_lifetime_safety_used_here : Note<"later used here">;
-def note_lifetime_safety_invalidated_here : Note<"invalidated here">;
-def note_lifetime_safety_destroyed_here : Note<"destroyed here">;
-def note_lifetime_safety_freed_here : Note<"freed here">;
+def note_lifetime_safety_invalidated_here : Note<"%0 is invalidated here">;
+def note_lifetime_safety_destroyed_here : Note<"%0 is destroyed here">;
+def note_lifetime_safety_freed_here : Note<"%0 is freed here">;
def note_lifetime_safety_returned_here : Note<"returned here">;
def note_lifetime_safety_moved_here : Note<"potentially moved here">;
def note_lifetime_safety_dangling_field_here: Note<"this field dangles">;
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h
index 4bde272fb40a1..1047aecf863fb 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -87,13 +87,15 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
unsigned DiagID = MovedExpr
? diag::warn_lifetime_safety_use_after_scope_moved
: diag::warn_lifetime_safety_use_after_scope;
+ std::string DestroyedSubject = getDiagSubjectDescription(IssueExpr);
S.Diag(IssueExpr->getExprLoc(), DiagID)
- << getDiagSubjectDescription(IssueExpr) << IssueExpr->getSourceRange();
+ << DestroyedSubject << IssueExpr->getSourceRange();
if (MovedExpr)
S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here)
<< MovedExpr->getSourceRange();
- S.Diag(FreeLoc, diag::note_lifetime_safety_destroyed_here);
+ S.Diag(FreeLoc, diag::note_lifetime_safety_destroyed_here)
+ << DestroyedSubject;
reportAliasingChain(ExprChain);
@@ -167,13 +169,10 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
auto WarnDiag = isa<CXXDeleteExpr>(InvalidationExpr)
? diag::warn_lifetime_safety_use_after_free
: diag::warn_lifetime_safety_invalidation;
- auto UseDiag = isa<CXXDeleteExpr>(InvalidationExpr)
- ? diag::note_lifetime_safety_freed_here
- : diag::note_lifetime_safety_invalidated_here;
+ std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
S.Diag(IssueExpr->getExprLoc(), WarnDiag)
- << getDiagSubjectDescription(IssueExpr) << IssueExpr->getSourceRange();
- S.Diag(InvalidationExpr->getExprLoc(), UseDiag)
- << InvalidationExpr->getSourceRange();
+ << InvalidatedSubject << IssueExpr->getSourceRange();
+ reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)
<< UseExpr->getSourceRange();
}
@@ -183,14 +182,11 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
auto WarnDiag = isa<CXXDeleteExpr>(InvalidationExpr)
? diag::warn_lifetime_safety_use_after_free
: diag::warn_lifetime_safety_invalidation;
- auto UseDiag = isa<CXXDeleteExpr>(InvalidationExpr)
- ? diag::note_lifetime_safety_freed_here
- : diag::note_lifetime_safety_invalidated_here;
+ std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
S.Diag(PVD->getSourceRange().getBegin(), WarnDiag)
- << getDiagSubjectDescription(PVD) << PVD->getSourceRange();
- S.Diag(InvalidationExpr->getExprLoc(), UseDiag)
- << InvalidationExpr->getSourceRange();
+ << InvalidatedSubject << PVD->getSourceRange();
+ reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)
<< UseExpr->getSourceRange();
}
@@ -198,16 +194,12 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
void reportInvalidatedField(const Expr *IssueExpr,
const FieldDecl *DanglingField,
const Expr *InvalidationExpr) override {
- auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
- ? diag::note_lifetime_safety_freed_here
- : diag::note_lifetime_safety_invalidated_here;
+ std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
S.Diag(IssueExpr->getExprLoc(),
diag::warn_lifetime_safety_invalidated_field)
- << getDiagSubjectDescription(IssueExpr)
- << getDiagSubjectDescription(DanglingField)
+ << InvalidatedSubject << getDiagSubjectDescription(DanglingField)
<< IssueExpr->getSourceRange();
- S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
- << InvalidationExpr->getSourceRange();
+ reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
S.Diag(DanglingField->getLocation(),
diag::note_lifetime_safety_dangling_field_here)
<< DanglingField->getEndLoc();
@@ -216,15 +208,12 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
void reportInvalidatedField(const ParmVarDecl *PVD,
const FieldDecl *DanglingField,
const Expr *InvalidationExpr) override {
- auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
- ? diag::note_lifetime_safety_freed_here
- : diag::note_lifetime_safety_invalidated_here;
+ std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
S.Diag(PVD->getSourceRange().getBegin(),
diag::warn_lifetime_safety_invalidated_field)
- << getDiagSubjectDescription(PVD)
- << getDiagSubjectDescription(DanglingField) << PVD->getSourceRange();
- S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
- << InvalidationExpr->getSourceRange();
+ << InvalidatedSubject << getDiagSubjectDescription(DanglingField)
+ << PVD->getSourceRange();
+ reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
S.Diag(DanglingField->getLocation(),
diag::note_lifetime_safety_dangling_field_here)
<< DanglingField->getEndLoc();
@@ -233,16 +222,12 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
void reportInvalidatedGlobal(const Expr *IssueExpr,
const VarDecl *DanglingGlobal,
const Expr *InvalidationExpr) override {
- auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
- ? diag::note_lifetime_safety_freed_here
- : diag::note_lifetime_safety_invalidated_here;
+ std::string InvalidatedSubject = getDiagSubjectDescription(IssueExpr);
S.Diag(IssueExpr->getExprLoc(),
diag::warn_lifetime_safety_invalidated_global)
- << getDiagSubjectDescription(IssueExpr)
- << getDiagSubjectDescription(DanglingGlobal)
+ << InvalidatedSubject << getDiagSubjectDescription(DanglingGlobal)
<< IssueExpr->getSourceRange();
- S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
- << InvalidationExpr->getSourceRange();
+ reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
if (DanglingGlobal->isStaticLocal() || DanglingGlobal->isStaticDataMember())
S.Diag(DanglingGlobal->getLocation(),
diag::note_lifetime_safety_dangling_static_here)
@@ -256,15 +241,12 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
void reportInvalidatedGlobal(const ParmVarDecl *PVD,
const VarDecl *DanglingGlobal,
const Expr *InvalidationExpr) override {
- auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
- ? diag::note_lifetime_safety_freed_here
- : diag::note_lifetime_safety_invalidated_here;
+ std::string InvalidatedSubject = getDiagSubjectDescription(PVD);
S.Diag(PVD->getSourceRange().getBegin(),
diag::warn_lifetime_safety_invalidated_global)
- << getDiagSubjectDescription(PVD)
- << getDiagSubjectDescription(DanglingGlobal) << PVD->getSourceRange();
- S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
- << InvalidationExpr->getSourceRange();
+ << InvalidatedSubject << getDiagSubjectDescription(DanglingGlobal)
+ << PVD->getSourceRange();
+ reportInvalidationSite(InvalidationExpr, InvalidatedSubject);
if (DanglingGlobal->isStaticLocal() || DanglingGlobal->isStaticDataMember())
S.Diag(DanglingGlobal->getLocation(),
diag::note_lifetime_safety_dangling_static_here)
@@ -442,6 +424,15 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
}
private:
+ void reportInvalidationSite(const Expr *InvalidationExpr,
+ StringRef InvalidatedSubject) {
+ auto Diag = isa<CXXDeleteExpr>(InvalidationExpr)
+ ? diag::note_lifetime_safety_freed_here
+ : diag::note_lifetime_safety_invalidated_here;
+ S.Diag(InvalidationExpr->getExprLoc(), Diag)
+ << InvalidatedSubject << InvalidationExpr->getSourceRange();
+ }
+
std::string getLifetimeBoundFixItText(SourceLocation Loc, bool LeadingSpace,
bool AllowGNUAttrMacro = true) {
StringRef Spelling = S.getLangOpts().LifetimeSafetyLifetimeBoundMacro;
diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
index cef3397b57a6f..98c528516b8e7 100644
--- a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
+++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
@@ -277,21 +277,21 @@ View return_view_field(const ViewProvider& v) { // expected-warning {{paramet
void test_get_on_temporary_pointer() {
const ReturnsSelf* s_ref = &ReturnsSelf().get(); // expected-warning {{temporary object does not live long enough}}.
- // expected-note at -1 {{destroyed here}}
+ // expected-note at -1 {{temporary object is destroyed here}}
// expected-note at -2 {{result of call to 'get' 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 {{temporary object does not live long enough}}.
- // expected-note at -1 {{destroyed here}}
+ // expected-note at -1 {{temporary object is destroyed here}}
// expected-note at -2 {{result of call to 'get' 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 {{temporary object does not live long enough}}.
- // expected-note at -1 {{destroyed here}}
+ // expected-note at -1 {{temporary object is destroyed here}}
// expected-note at -2 {{result of call to 'getView' aliases the storage of temporary object}}
(void)sv; // expected-note {{later used here}}
}
@@ -604,7 +604,7 @@ void uaf_via_inferred_lifetimebound() {
int local;
f = return_lambda_capturing_param(local); // expected-warning {{local variable 'local' does not live long enough}} \
// expected-note {{result of call to 'return_lambda_capturing_param' aliases the storage of local variable 'local'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)f; // expected-note {{later used here}}
}
@@ -628,7 +628,7 @@ void test_inference() {
MyObj obj;
ptr = create_target(obj); // expected-warning {{local variable 'obj' does not live long enough}} \
// expected-note {{result of call to 'create_target' aliases the storage of local variable 'obj'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)ptr; // expected-note {{later used here}}
}
} // namespace make_unique_suggestion
@@ -636,12 +636,12 @@ void test_inference() {
namespace new_allocation_suggestion {
View* MakeView(const MyObj& in) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
- return new View(in); // expected-note {{param returned here}} {{destroyed here}}
+ return new View(in); // expected-note {{param returned here}}
}
void test_new_allocation() {
View* v = MakeView(MyObj{}); // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'MakeView' aliases the storage of temporary object}}
(void)v; // expected-note {{later used here}}
}
diff --git a/clang/test/Sema/LifetimeSafety/invalidations.cpp b/clang/test/Sema/LifetimeSafety/invalidations.cpp
index 301822f066de8..c2ac105855d07 100644
--- a/clang/test/Sema/LifetimeSafety/invalidations.cpp
+++ b/clang/test/Sema/LifetimeSafety/invalidations.cpp
@@ -8,7 +8,7 @@ namespace SimpleResize {
void IteratorInvalidAfterResize(int new_size) {
std::vector<int> v;
auto it = std::begin(v); // expected-warning {{local variable 'v' is later invalidated}}
- v.resize(new_size); // expected-note {{invalidated here}}
+ v.resize(new_size); // expected-note {{local variable 'v' is invalidated here}}
*it; // expected-note {{later used here}}
}
@@ -53,7 +53,7 @@ void InvalidateBeforeSwapIterators(std::vector<int> v1, std::vector<int> v2) {
if (it1 == std::end(v1) || it2 == std::end(v2)) return;
*it1 = 0; // ok
*it2 = 0; // ok
- v1.clear(); // expected-note {{invalidated here}}
+ v1.clear(); // expected-note {{parameter 'v1' is invalidated here}}
*it1 = 0; // expected-note {{later used here}}
// FIXME: Handle invalidating functions like std::swap.
std::swap(it1, it2);
@@ -67,7 +67,7 @@ void InvalidateBeforeSwapContainers(std::vector<int> v1, std::vector<int> v2) {
if (it1 == std::end(v1) || it2 == std::end(v2)) return;
*it1 = 0; // ok
*it2 = 0; // ok
- v1.clear(); // expected-note {{invalidated here}}
+ v1.clear(); // expected-note {{parameter 'v1' is invalidated here}}
*it1 = 0; // expected-note {{later used here}}
}
} // namespace InvalidateBeforeSwap
@@ -81,7 +81,7 @@ void SameConditionInvalidatesThenValidatesIterator() {
if (it == container.end()) return;
const bool a = A();
if (a) {
- container.clear(); // expected-note {{invalidated here}}
+ container.clear(); // expected-note {{local variable 'container' is invalidated here}}
}
if (a) {
it = container.begin();
@@ -112,7 +112,7 @@ void MergeWithDifferentContainerValuesInvalidated() {
} else {
it = std::find(v3.begin(), v3.end(), 10);
}
- v2.clear(); // expected-note {{invalidated here}}
+ v2.clear(); // expected-note {{local variable 'v2' is invalidated here}}
*it = 20; // expected-note {{later used here}}
}
} // namespace IteratorWithMultipleContainers
@@ -123,7 +123,7 @@ void IteratorInvalidationInAForLoop(std::vector<int> v) {
it != std::end(v);
++it) { // expected-note {{later used here}}
if (Bool()) {
- v.erase(it); // expected-note {{invalidated here}}
+ v.erase(it); // expected-note {{parameter 'v' is invalidated here}}
}
}
}
@@ -132,7 +132,7 @@ void IteratorInvalidationInAWhileLoop(std::vector<int> v) {
auto it = std::begin(v); // expected-warning {{parameter 'v' is later invalidated}}
while (it != std::end(v)) {
if (Bool()) {
- v.erase(it); // expected-note {{invalidated here}}
+ v.erase(it); // expected-note {{parameter 'v' is invalidated here}}
}
++it; // expected-note {{later used here}}
}
@@ -157,7 +157,7 @@ void IteratorInvalidationInAForeachLoop(std::vector<int> v) {
for (int& x : v) { // expected-warning {{parameter 'v' is later invalidated}} \
// expected-note {{later used here}}
if (x % 2 == 0) {
- v.erase(std::find(v.begin(), v.end(), 1)); // expected-note {{invalidated here}}
+ v.erase(std::find(v.begin(), v.end(), 1)); // expected-note {{parameter 'v' is invalidated here}}
}
}
}
@@ -185,7 +185,7 @@ void IteratorCheckedAfterFind(std::vector<int> v) {
void IteratorCheckedAfterFindThenErased(std::vector<int> v) {
auto it = std::find(std::begin(v), std::end(v), 3); // expected-warning {{parameter 'v' is later invalidated}}
if (it != std::end(v)) {
- v.erase(it); // expected-note {{invalidated here}}
+ v.erase(it); // expected-note {{parameter 'v' is invalidated here}}
}
*it; // expected-note {{later used here}}
}
@@ -202,7 +202,7 @@ void UseReturnedIteratorAfterInsert(std::vector<int> v) {
void UseInvalidIteratorAfterInsert(std::vector<int> v) {
auto it = std::begin(v); // expected-warning {{parameter 'v' is later invalidated}}
- v.insert(it, 10); // expected-note {{invalidated here}}
+ v.insert(it, 10); // expected-note {{parameter 'v' is invalidated here}}
if (it != std::end(v)) { // expected-note {{later used here}}
*it;
}
@@ -221,7 +221,7 @@ void IteratorValidAfterInsert(std::vector<int> v) {
void IteratorInvalidAfterInsert(std::vector<int> v, int value) {
auto it = std::begin(v); // expected-warning {{parameter 'v' is later invalidated}}
- v.insert(it, 0); // expected-note {{invalidated here}}
+ v.insert(it, 0); // expected-note {{parameter 'v' is invalidated here}}
*it; // expected-note {{later used here}}
}
} // namespace SimpleStdInsert
@@ -231,7 +231,7 @@ void IteratorUsedAfterErase(std::vector<int> v) {
auto it = std::begin(v); // expected-warning {{parameter 'v' is later invalidated}}
for (; it != std::end(v); ++it) { // expected-note {{later used here}}
if (*it > 3) {
- v.erase(it); // expected-note {{invalidated here}}
+ v.erase(it); // expected-note {{parameter 'v' is invalidated here}}
}
}
}
@@ -239,7 +239,7 @@ void IteratorUsedAfterErase(std::vector<int> v) {
void IteratorUsedAfterPushBackParam(std::vector<int>& v) { // expected-warning {{parameter 'v' is later invalidated}}
auto it = std::begin(v);
if (it != std::end(v) && *it == 3) {
- v.push_back(4); // expected-note {{invalidated here}}
+ v.push_back(4); // expected-note {{parameter 'v' is invalidated here}}
}
++it; // expected-note {{later used here}}
}
@@ -247,7 +247,7 @@ void IteratorUsedAfterPushBackParam(std::vector<int>& v) { // expected-warning {
void IteratorUsedAfterPushBack(std::vector<int> v) {
auto it = std::begin(v); // expected-warning {{parameter 'v' is later invalidated}}
if (it != std::end(v) && *it == 3) {
- v.push_back(4); // expected-note {{invalidated here}}
+ v.push_back(4); // expected-note {{parameter 'v' is invalidated here}}
}
++it; // expected-note {{later used here}}
}
@@ -256,14 +256,14 @@ void IteratorUsedAfterPreIncrement() {
std::vector<int> v;
auto it = v.begin(); // expected-warning {{local variable 'v' is later invalidated}}
auto next = ++it;
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{local variable 'v' is invalidated here}}
(void)*next; // expected-note {{later used here}}
}
void IteratorUsedAfterPostDecrement(std::vector<int> v) {
auto it = v.rbegin(); // expected-warning {{parameter 'v' is later invalidated}}
auto prev = it--;
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{parameter 'v' is invalidated here}}
(void)*prev; // expected-note {{later used here}}
}
@@ -271,21 +271,21 @@ void IteratorUsedAfterAddition() {
std::vector<int> v;
auto it = v.cbegin(); // expected-warning {{local variable 'v' is later invalidated}}
auto next = it + 5;
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{local variable 'v' is invalidated here}}
(void)*next; // expected-note {{later used here}}
}
void IteratorUsedAfterReverseSubtraction(std::vector<int> v) {
auto it = v.crbegin(); // expected-warning {{parameter 'v' is later invalidated}}
auto prev = 5 - it;
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{parameter 'v' is invalidated here}}
(void)*prev; // expected-note {{later used here}}
}
void IteratorUsedAfterAddAdd(std::vector<int> v) {
auto it = v.cbegin(); // expected-warning {{parameter 'v' is later invalidated}}
auto next = (it + 5) + 5;
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{parameter 'v' is invalidated here}}
(void)*next; // expected-note {{later used here}}
}
@@ -293,21 +293,21 @@ void IteratorUsedAfterMixedAddition() {
std::vector<int> v;
auto it = v.cbegin(); // expected-warning {{local variable 'v' is later invalidated}}
auto next = 1 + it + 2 + 3;
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{local variable 'v' is invalidated here}}
(void)*next; // expected-note {{later used here}}
}
void IteratorUsedAfterPreIncrementAddAssign(std::vector<int> v) {
auto it = v.begin(); // expected-warning {{parameter 'v' is later invalidated}}
it = ++it + 1 + 2;
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{parameter 'v' is invalidated here}}
(void)*it; // expected-note {{later used here}}
}
void IteratorUsedAfterBeginAddAssign() {
std::vector<int> v;
auto it = v.begin() + 1; // expected-warning {{local variable 'v' is later invalidated}}
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{local variable 'v' is invalidated here}}
(void)*it; // expected-note {{later used here}}
}
@@ -315,7 +315,7 @@ void IteratorUsedAfterStdBeginAddAssign() {
std::vector<int> v;
std::vector<int>::iterator it;
it = std::begin(v) + 1; // expected-warning {{local variable 'v' is later invalidated}}
- v.push_back(1); // expected-note {{invalidated here}}
+ v.push_back(1); // expected-note {{local variable 'v' is invalidated here}}
(void)*it; // expected-note {{later used here}}
}
} // namespace SimpleInvalidIterators
@@ -325,13 +325,13 @@ void IteratorInvalidatedThroughLocalReferenceAlias() {
std::vector<int> vv;
std::vector<int> &v = vv;
auto it = vv.begin(); // expected-warning {{local variable 'vv' is later invalidated}}
- v.push_back(42); // expected-note {{invalidated here}}
+ v.push_back(42); // expected-note {{local variable 'vv' is invalidated here}}
(void)it; // expected-note {{later used here}}
}
void IteratorInvalidatedThroughPointerParameter(std::vector<int> *v) { // expected-warning {{parameter 'v' is later invalidated}}
auto it = v->begin();
- v->push_back(42); // expected-note {{invalidated here}}
+ v->push_back(42); // expected-note {{parameter 'v' is invalidated here}}
(void)it; // expected-note {{later used here}}
}
@@ -348,7 +348,7 @@ void ParenthesizedContainerInvalidatesIterator() {
namespace ContainerObjectAliases {
// FIXME: Distinguish owner-borrow from content-borrow.
void PointerParameterObjectUseIsOk(std::vector<int> *v) { // expected-warning {{parameter 'v' is later invalidated}}
- v->push_back(42); // expected-note {{invalidated here}}
+ v->push_back(42); // expected-note {{parameter 'v' is invalidated here}}
(void)v; // expected-note {{later used here}}
}
@@ -356,7 +356,7 @@ void PointerParameterObjectUseIsOk(std::vector<int> *v) { // expected-warning {{
void LocalPointerAliasObjectUseIsOk() {
std::vector<int> vv;
std::vector<int> *v = &vv; // expected-warning {{local variable 'vv' is later invalidated}}
- v->push_back(42); // expected-note {{invalidated here}}
+ v->push_back(42); // expected-note {{local variable 'vv' is invalidated here}}
(void)*v; // expected-note {{later used here}}
}
@@ -364,7 +364,7 @@ void LocalPointerAliasObjectUseIsOk() {
void LocalReferenceAliasObjectUseIsOk() {
std::vector<int> vv;
std::vector<int> &v = vv; // expected-warning {{local variable 'vv' is later invalidated}}
- v.push_back(42); // expected-note {{invalidated here}}
+ v.push_back(42); // expected-note {{local variable 'vv' is invalidated here}}
(void)v; // expected-note {{later used here}}
}
} // namespace ContainerObjectAliases
@@ -375,7 +375,7 @@ namespace ElementReferences {
void ReferenceToVectorElement() {
std::vector<int> v = {1, 2, 3};
int& ref = v[0]; // expected-warning {{local variable 'v' is later invalidated}}
- v.push_back(4); // expected-note {{invalidated here}}
+ v.push_back(4); // expected-note {{local variable 'v' is invalidated here}}
ref = 10; // expected-note {{later used here}}
(void)ref;
}
@@ -383,14 +383,14 @@ void ReferenceToVectorElement() {
void PointerRefToVectorElement() {
std::vector<int*> v = {nullptr, nullptr};
int*& ref = v[0]; // expected-warning {{local variable 'v' is later invalidated}}
- v.push_back(nullptr); // expected-note {{invalidated here}}
+ v.push_back(nullptr); // expected-note {{local variable 'v' is invalidated here}}
ref = nullptr; // expected-note {{later used here}}
}
void PointerToVectorElement() {
std::vector<int> v = {1, 2, 3};
int* ptr = &v[0]; // expected-warning {{local variable 'v' is later invalidated}}
- v.resize(100); // expected-note {{invalidated here}}
+ v.resize(100); // expected-note {{local variable 'v' is invalidated here}}
*ptr = 10; // expected-note {{later used here}}
}
@@ -403,7 +403,7 @@ void SelfInvalidatingMap() {
// On the other hand, std::flat_map (since C++23) does not provide pointer stability on
// insertion and following is unsafe for this container.
mp[1] = "42";
- mp[2] // expected-note {{invalidated here}}
+ mp[2] // expected-note {{local variable 'mp' is invalidated here}}
=
mp[1]; // expected-warning {{local variable 'mp' is later invalidated}} expected-note {{later used here}}
}
@@ -412,7 +412,7 @@ void InvalidateErase() {
std::flat_map<int, std::string> mp;
// None of these containers provide iterator stability. So following is unsafe:
auto it = mp.find(3); // expected-warning {{local variable 'mp' is later invalidated}}
- mp.erase(mp.find(4)); // expected-note {{invalidated here}}
+ mp.erase(mp.find(4)); // expected-note {{local variable 'mp' is invalidated here}}
if (it != mp.end()) // expected-note {{later used here}}
*it;
}
@@ -422,12 +422,12 @@ namespace Strings {
void append(std::string str) {
std::string_view view = str; // expected-warning {{parameter 'str' is later invalidated}}
- str += "456"; // expected-note {{invalidated here}}
+ str += "456"; // expected-note {{parameter 'str' is invalidated here}}
(void)view; // expected-note {{later used here}}
}
void reassign(std::string str, std::string str2) {
std::string_view view = str; // expected-warning {{parameter 'str' is later invalidated}}
- str = str2; // expected-note {{invalidated here}}
+ str = str2; // expected-note {{parameter 'str' is invalidated here}}
(void)view; // expected-note {{later used here}}
}
} // namespace Strings
@@ -437,7 +437,7 @@ void ReassigningAfterMove(std::string str, std::string str2) {
std::string_view view = str; // expected-warning {{parameter 'str' is later invalidated}}
std::vector<std::string> someStorage;
someStorage.push_back(std::move(str));
- str = str2; // expected-note {{invalidated here}}
+ str = str2; // expected-note {{parameter 'str' is invalidated here}}
(void)view; // expected-note {{later used here}}
}
@@ -480,7 +480,7 @@ void Invalidate1Use2ViaRefIsOk() {
S s;
auto it = s.strings2.begin(); // expected-warning {{local variable 's' is later invalidated}}
auto& strings1 = s.strings1;
- strings1.push_back("1"); // expected-note {{invalidated here}}
+ strings1.push_back("1"); // expected-note {{local variable 's' is invalidated here}}
*it; // expected-note {{later used here}}
}
void Invalidate1UseSIsOk() {
@@ -493,14 +493,14 @@ void Invalidate1UseSIsOk() {
void PointerToContainerIsOk() {
std::vector<std::string> s;
std::vector<std::string>* p = &s; // expected-warning {{local variable 's' is later invalidated}}
- p->push_back("1"); // expected-note {{invalidated here}}
+ p->push_back("1"); // expected-note {{local variable 's' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
void IteratorFromPointerToContainerIsInvalidated() {
std::vector<std::string> s;
std::vector<std::string>* p = &s; // expected-warning {{local variable 's' is later invalidated}}
auto it = p->begin();
- p->push_back("1"); // expected-note {{invalidated here}}
+ p->push_back("1"); // expected-note {{local variable 's' is invalidated here}}
*it; // expected-note {{later used here}}
}
// FIXME: Distinguish invalidating an element's contents from invalidating
@@ -508,7 +508,7 @@ void IteratorFromPointerToContainerIsInvalidated() {
void ChangingRegionOwnedByContainerIsOk() {
std::vector<std::string> subdirs;
for (std::string& path : subdirs) // expected-warning {{local variable 'subdirs' is later invalidated}} expected-note {{later used here}}
- path = std::string(); // expected-note {{invalidated here}}
+ path = std::string(); // expected-note {{local variable 'subdirs' is invalidated here}}
}
} // namespace ContainersAsFields
@@ -522,7 +522,7 @@ struct SinkOwnerBorrow {
SinkOwnerBorrow(std::string *dest, int n) : dest_(dest) { // expected-warning {{parameter 'dest' escapes to the field 'dest_' and is later invalidated}}
if (n > 0)
- dest->clear(); // expected-note {{invalidated here}}
+ dest->clear(); // expected-note {{parameter 'dest' is invalidated here}}
}
};
@@ -531,7 +531,7 @@ struct SinkInteriorBorrow {
SinkInteriorBorrow(std::string *dest, int n) : dest_(dest->data()) { // expected-warning {{parameter 'dest' escapes to the field 'dest_' and is later invalidated}}
if (n > 0)
- dest->clear(); // expected-note {{invalidated here}}
+ dest->clear(); // expected-note {{parameter 'dest' is invalidated here}}
}
};
@@ -548,39 +548,39 @@ struct S {
void InvalidatedFieldLocalVector() {
std::vector<std::string> strings;
FieldFromLocalVector = *strings.begin(); // expected-warning {{local variable 'strings' escapes to the field 'FieldFromLocalVector' and is later invalidated}}
- strings.push_back("1"); // expected-note {{invalidated here}}
+ strings.push_back("1"); // expected-note {{local variable 'strings' is invalidated here}}
}
void InvalidatedFieldByValueParamVector(std::vector<std::string> strings) {
FieldFromByValueParamVector = *strings.begin(); // expected-warning {{parameter 'strings' escapes to the field 'FieldFromByValueParamVector' and is later invalidated}}
- strings.push_back("1"); // expected-note {{invalidated here}}
+ strings.push_back("1"); // expected-note {{parameter 'strings' is invalidated here}}
}
void InvalidatedFieldLocalString() {
std::string s;
FieldFromLocalString = s; // expected-warning {{local variable 's' escapes to the field 'FieldFromLocalString' and is later invalidated}}
- s.clear(); // expected-note {{invalidated here}}
+ s.clear(); // expected-note {{local variable 's' is invalidated here}}
}
void InvalidatedFieldByValueParamString(std::string s) {
FieldFromByValueParamString = s; // expected-warning {{parameter 's' escapes to the field 'FieldFromByValueParamString' and is later invalidated}}
- s.clear(); // expected-note {{invalidated here}}
+ s.clear(); // expected-note {{parameter 's' is invalidated here}}
}
void InvalidatedFieldRefParamString(std::string &s) { // expected-warning {{parameter 's' escapes to the field 'FieldFromRefParamString' and is later invalidated}}
FieldFromRefParamString = s;
- s.~basic_string(); // expected-note {{invalidated here}}
+ s.~basic_string(); // expected-note {{parameter 's' is invalidated here}}
}
void InvalidatedFieldDelete() {
int *p = new int; // expected-warning {{allocated object escapes to the field 'FieldFromNew' and is later invalidated}}
FieldFromNew = p;
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
}
void InvalidatedFieldDeleteParam(int *p) { // expected-warning {{parameter 'p' escapes to the field 'FieldFromPointerParam' and is later invalidated}}
FieldFromPointerParam = p;
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{parameter 'p' is freed here}}
}
void FieldReassignedBeforeInvalidation() {
@@ -608,41 +608,41 @@ struct S {
void InvalidatedGlobalLocalVector() {
std::vector<std::string> strings;
GlobalFromLocalVector = *strings.begin(); // expected-warning {{local variable 'strings' escapes to the global variable 'GlobalFromLocalVector' and is later invalidated}}
- strings.push_back("1"); // expected-note {{invalidated here}}
+ strings.push_back("1"); // expected-note {{local variable 'strings' is invalidated here}}
}
void InvalidatedGlobalByValueParamString(std::string s) {
GlobalFromByValueParamString = s; // expected-warning {{parameter 's' escapes to the global variable 'GlobalFromByValueParamString' and is later invalidated}}
- s.clear(); // expected-note {{invalidated here}}
+ s.clear(); // expected-note {{parameter 's' is invalidated here}}
}
void InvalidatedGlobalRefParamString(std::string &s) { // expected-warning {{parameter 's' escapes to the global variable 'GlobalFromRefParamString' and is later invalidated}}
GlobalFromRefParamString = s;
- s.~basic_string(); // expected-note {{invalidated here}}
+ s.~basic_string(); // expected-note {{parameter 's' is invalidated here}}
}
void InvalidatedGlobalDelete() {
int *p = new int; // expected-warning {{allocated object escapes to the global variable 'GlobalFromNew' and is later invalidated}}
GlobalFromNew = p;
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
}
void InvalidatedGlobalDeleteParam(int *p) { // expected-warning {{parameter 'p' escapes to the global variable 'GlobalFromPointerParam' and is later invalidated}}
GlobalFromPointerParam = p;
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{parameter 'p' is freed here}}
}
void InvalidatedStaticLocalString() {
static std::string_view StaticFromLocalString; // expected-note {{this static storage dangles}}
std::string s;
StaticFromLocalString = s; // expected-warning {{local variable 's' escapes to the static variable 'StaticFromLocalString' and is later invalidated}}
- s.clear(); // expected-note {{invalidated here}}
+ s.clear(); // expected-note {{local variable 's' is invalidated here}}
}
void InvalidatedStaticMemberString() {
std::string s;
S::StaticMember = s; // expected-warning {{local variable 's' escapes to the static variable 'StaticMember' and is later invalidated}}
- s.clear(); // expected-note {{invalidated here}}
+ s.clear(); // expected-note {{local variable 's' is invalidated here}}
}
void GlobalReassignedBeforeInvalidation() {
@@ -715,14 +715,14 @@ void SetExtractDoesNotInvalidateOthers() {
void SetClearInvalidates() {
std::set<int> s;
auto it = s.begin(); // expected-warning {{local variable 's' is later invalidated}}
- s.clear(); // expected-note {{invalidated here}}
+ s.clear(); // expected-note {{local variable 's' is invalidated here}}
*it; // expected-note {{later used here}}
}
void MapClearInvalidates() {
std::map<int, int> m;
auto it = m.begin(); // expected-warning {{local variable 'm' is later invalidated}}
- m.clear(); // expected-note {{invalidated here}}
+ m.clear(); // expected-note {{local variable 'm' is invalidated here}}
*it; // expected-note {{later used here}}
}
@@ -741,7 +741,7 @@ void MapSubscriptMultipleCallsDoesNotInvalidate(std::map<int, int> mp, int a, in
void FlatMapSubscriptMultipleCallsInvalidate(std::flat_map<int, int> mp, int a, int b) {
PrintMax(mp[a], mp[b]); // expected-warning {{parameter 'mp' is later invalidated}} \
- // expected-note {{invalidated here}} \
+ // expected-note {{parameter 'mp' is invalidated here}} \
// expected-note {{later used here}}
}
@@ -752,7 +752,7 @@ void captured_view_invalidated_by_owner() {
std::string s = "42";
std::string_view p = s; // expected-warning {{local variable 's' is later invalidated}}
auto lambda = [=]() { return p; };
- s.push_back('c'); // expected-note {{invalidated here}}
+ s.push_back('c'); // expected-note {{local variable 's' is invalidated here}}
lambda(); // expected-note {{later used here}}
}
@@ -760,7 +760,7 @@ void multiple_captures_one_invalidated() {
std::string s1 = "a", s2 = "b";
std::string_view p1 = s1, p2 = s2; // expected-warning {{local variable 's1' is later invalidated}}
auto lambda = [=]() { return p1.size() + p2.size(); };
- s1.clear(); // expected-note {{invalidated here}}
+ s1.clear(); // expected-note {{local variable 's1' is invalidated here}}
lambda(); // expected-note {{later used here}}
}
@@ -794,7 +794,7 @@ struct S {
void baz(){
std::vector<std::string> vec = {"42"};
v = vec[0]; // expected-warning {{local variable 'vec' is later invalidated}}
- vec.push_back("1"); // expected-note {{invalidated here}}
+ vec.push_back("1"); // expected-note {{local variable 'vec' is invalidated here}}
bar(); // expected-note {{later used here}}
v = nullptr;
}
@@ -807,7 +807,7 @@ void function_captured_ref_invalidated() {
std::vector<int> v;
v.push_back(1);
std::function<void()> f = [&r = v[0]]() { (void)r; }; // expected-warning {{local variable 'v' is later invalidated}}
- v.push_back(2); // expected-note {{invalidated here}}
+ v.push_back(2); // expected-note {{local variable 'v' is invalidated here}}
(void)f; // expected-note {{later used here}}
}
@@ -819,7 +819,7 @@ namespace explicit_destructor {
void explicit_destructor_invalidates_pointer() {
std::string s = "42";
const char *p = s.data(); // expected-warning {{local variable 's' is later invalidated}}
- s.~basic_string(); // expected-note {{invalidated here}}
+ s.~basic_string(); // expected-note {{local variable 's' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -827,7 +827,7 @@ void pointer_destructor_invalidates_pointer() {
char storage[sizeof(std::string)];
std::string *obj = new (storage) std::string("42"); // expected-warning {{local variable 'storage' is later invalidated}}
const char *p = obj->data();
- obj->~basic_string(); // expected-note {{invalidated here}}
+ obj->~basic_string(); // expected-note {{local variable 'storage' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -835,7 +835,7 @@ void destroy_at_invalidates_pointer() {
char storage[sizeof(std::string)];
std::string *obj = new (storage) std::string("42"); // expected-warning {{local variable 'storage' is later invalidated}}
const char *p = obj->data();
- std::destroy_at(obj); // expected-note {{invalidated here}}
+ std::destroy_at(obj); // expected-note {{local variable 'storage' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -853,7 +853,7 @@ void destroy_at_invalidates_array_pointer() {
std::string arr[1] = {"42"};
std::string (&arr_ref)[1] = arr;
const char *p = arr[0].data(); // expected-warning {{local variable 'arr' is later invalidated}}
- std::destroy_at(&arr_ref); // expected-note {{invalidated here}}
+ std::destroy_at(&arr_ref); // expected-note {{local variable 'arr' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -861,7 +861,7 @@ void reference_destructor_invalidates_pointer() {
std::string s = "42";
std::string &ref = s; // expected-warning {{local variable 's' is later invalidated}}
const char *p = ref.data();
- std::destroy_at(&ref); // expected-note {{invalidated here}}
+ std::destroy_at(&ref); // expected-note {{local variable 's' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -869,7 +869,7 @@ void destroy_at_ternary_operator(bool flag) {
std::string* str1 = new std::string; // expected-warning {{allocated object is later invalidated}}
std::string* str2 = new std::string;
const char *p = str1->data();
- std::destroy_at(flag ? str1 : str2); // expected-note {{invalidated here}}
+ std::destroy_at(flag ? str1 : str2); // expected-note {{allocated object is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -881,7 +881,7 @@ struct StringOwner {
void member_destructor_invalidates_pointer() {
StringOwner owner = {"42", "43"};
const char *p = owner.s.data(); // expected-warning {{local variable 'owner' is later invalidated}}
- owner.t.~basic_string(); // expected-note {{invalidated here}}
+ owner.t.~basic_string(); // expected-note {{local variable 'owner' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -892,7 +892,7 @@ namespace unique_ptr_invalidation {
void invalid_after_reset() {
std::unique_ptr<int> up(new int);
int *p = up.get(); // expected-warning {{local variable 'up' is later invalidated}}
- up.reset(); // expected-note {{invalidated here}}
+ up.reset(); // expected-note {{local variable 'up' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -900,14 +900,14 @@ void invalid_after_move_assign() {
std::unique_ptr<int> up(new int);
std::unique_ptr<int> other(new int);
int *p = up.get(); // expected-warning {{local variable 'up' is later invalidated}}
- up = std::move(other); // expected-note {{invalidated here}}
+ up = std::move(other); // expected-note {{local variable 'up' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
void invalid_after_null_assign() {
std::unique_ptr<int> up(new int);
int *p = up.get(); // expected-warning {{local variable 'up' is later invalidated}}
- up = nullptr; // expected-note {{invalidated here}}
+ up = nullptr; // expected-note {{local variable 'up' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
@@ -915,7 +915,7 @@ void invalid_after_ternary_reset(bool flag) {
std::unique_ptr<int> up(new int);
std::unique_ptr<int> other(new int);
int *p = flag ? up.get() : other.get(); // expected-warning {{local variable 'up' is later invalidated}}
- up.reset(); // expected-note {{invalidated here}}
+ up.reset(); // expected-note {{local variable 'up' is invalidated here}}
(void)*p; // expected-note {{later used here}}
}
diff --git a/clang/test/Sema/LifetimeSafety/safety-c.c b/clang/test/Sema/LifetimeSafety/safety-c.c
index 9ab2a57cb08a9..e9443899c9935 100644
--- a/clang/test/Sema/LifetimeSafety/safety-c.c
+++ b/clang/test/Sema/LifetimeSafety/safety-c.c
@@ -16,7 +16,7 @@ void simple_case(void) {
{
int i;
p = &i; // expected-warning {{local variable 'i' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'i' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -25,7 +25,7 @@ void chained_assignment(void) {
{
int i;
p = q = r = &i; // expected-warning {{local variable 'i' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'i' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -35,7 +35,7 @@ void conditional_branch(int cond) {
if (cond) {
int i;
p = &i; // expected-warning {{local variable 'i' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'i' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -46,7 +46,7 @@ void loop_with_break(int cond) {
if (cond) {
int i;
p = &i; // expected-warning {{local variable 'i' does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'i' is destroyed here}}
}
}
(void)*p; // expected-note {{later used here}}
@@ -64,7 +64,7 @@ void lifetimebound_call(void) {
int i;
p = identity(&i); // expected-warning {{local variable 'i' does not live long enough}} \
// expected-note {{result of call to 'identity' aliases the storage of local variable 'i'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'i' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -85,7 +85,7 @@ void struct_address_of_field(void) {
{
struct IntField holder;
p = &holder.field; // expected-warning {{local variable 'holder' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'holder' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -95,7 +95,8 @@ void conditional_operator_lifetimebound(int cond) {
int a, b;
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}}
+ } // expected-note {{local variable 'a' is destroyed here}} \
+ // expected-note {{local variable 'b' is destroyed here}}
(void)*p; // expected-note 2 {{later used here}}
}
@@ -109,7 +110,7 @@ void union_member(void) {
{
union IntOrPtr u;
p = &u.i; // expected-warning {{local variable 'u' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'u' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -125,7 +126,7 @@ void anonymous_union_member(void) {
{
struct AnonymousUnion u;
p = &u.i; // expected-warning {{local variable 'u' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'u' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp b/clang/test/Sema/LifetimeSafety/safety.cpp
index 65bfe69e854ac..abd3d9c61b784 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -55,7 +55,7 @@ void simple_case() {
{
MyObj s;
p = &s; // expected-warning {{local variable 's' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -64,7 +64,7 @@ void simple_case_gsl() {
{
MyObj s;
v = s; // expected-warning {{local variable 's' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -93,7 +93,7 @@ void pointer_chain() {
MyObj s;
p = &s; // expected-warning {{does not live long enough}}
q = p; // expected-note {{local variable 'p' aliases the storage of local variable 's'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*q; // expected-note {{later used here}}
}
@@ -103,7 +103,7 @@ void propagation_gsl() {
MyObj s;
v1 = s; // expected-warning {{local variable 's' does not live long enough}}
v2 = v1; // expected-note {{local variable 'v1' aliases the storage of local variable 's'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
v2.use(); // expected-note {{later used here}}
}
@@ -112,7 +112,7 @@ void multiple_uses_one_warning() {
{
MyObj s;
p = &s; // expected-warning {{does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*p; // expected-note {{later used here}}
// No second warning for the same loan.
p->id = 1;
@@ -127,7 +127,7 @@ void multiple_pointers() {
p = &s; // expected-warning {{does not live long enough}}
q = &s; // expected-warning {{does not live long enough}}
r = &s; // expected-warning {{does not live long enough}}
- } // expected-note 3 {{destroyed here}}
+ } // expected-note 3 {{local variable 's' is destroyed here}}
(void)*p; // expected-note {{later used here}}
(void)*q; // expected-note {{later used here}}
(void)*r; // expected-note {{later used here}}
@@ -139,7 +139,7 @@ void multiple_pointers_chained() {
MyObj s;
MyObj* obj1, *obj2;
p = obj1 = obj2 = &s; // expected-warning {{does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -158,11 +158,11 @@ void single_pointer_multiple_loans(bool cond) {
if (cond){
MyObj s;
p = &s; // expected-warning {{does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
else {
MyObj t;
p = &t; // expected-warning {{does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 't' is destroyed here}}
(void)*p; // expected-note 2 {{later used here}}
}
@@ -171,11 +171,11 @@ void single_pointer_multiple_loans_gsl(bool cond) {
if (cond){
MyObj s;
v = s; // expected-warning {{local variable 's' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
else {
MyObj t;
v = t; // expected-warning {{local variable 't' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 't' is destroyed here}}
v.use(); // expected-note 2 {{later used here}}
}
@@ -185,7 +185,7 @@ void if_branch(bool cond) {
if (cond) {
MyObj temp;
p = &temp; // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -195,7 +195,7 @@ void if_branch_potential(bool cond) {
if (cond) {
MyObj temp;
p = &temp; // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
if (!cond)
(void)*p; // expected-note {{later used here}}
else
@@ -208,7 +208,7 @@ void if_branch_gsl(bool cond) {
if (cond) {
MyObj temp;
v = temp; // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -223,7 +223,7 @@ void potential_together(bool cond) {
p_definite = &s; // expected-warning {{does not live long enough}}
if (cond)
p_maybe = &s; // expected-warning {{does not live long enough}}
- } // expected-note 2 {{destroyed here}}
+ } // expected-note 2 {{local variable 's' is destroyed here}}
(void)*p_definite; // expected-note {{later used here}}
if (!cond)
(void)*p_maybe; // expected-note {{later used here}}
@@ -237,7 +237,7 @@ void overrides_potential(bool cond) {
MyObj s;
q = &s; // expected-warning {{does not live long enough}}
p = q;
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
if (cond) {
// 'q' is conditionally "rescued". 'p' is not.
@@ -256,7 +256,7 @@ void due_to_conditional_killing(bool cond) {
{
MyObj s;
q = &s; // expected-warning {{does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
if (cond) {
// 'q' is conditionally "rescued". 'p' is not.
q = &safe;
@@ -269,7 +269,7 @@ void for_loop_use_after_loop_body(MyObj safe) {
for (int i = 0; i < 1; ++i) {
MyObj s;
p = &s; // expected-warning {{does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -289,7 +289,7 @@ void for_loop_gsl() {
for (int i = 0; i < 1; ++i) {
MyObj s;
v = s; // expected-warning {{local variable 's' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -300,7 +300,7 @@ void for_loop_use_before_loop_body(MyObj safe) {
(void)*p; // expected-note {{later used here}}
MyObj s;
p = &s; // expected-warning {{does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*p;
}
@@ -311,7 +311,7 @@ void loop_with_break(bool cond) {
if (cond) {
MyObj temp;
p = &temp; // expected-warning {{does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp' is destroyed here}}
}
}
(void)*p; // expected-note {{later used here}}
@@ -324,7 +324,7 @@ void loop_with_break_gsl(bool cond) {
if (cond) {
MyObj temp;
v = temp; // expected-warning {{local variable 'temp' does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp' is destroyed here}}
}
}
v.use(); // expected-note {{later used here}}
@@ -338,7 +338,7 @@ void multiple_expiry_of_same_loan(bool cond) {
MyObj unsafe;
if (cond) {
p = &unsafe; // expected-warning {{does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'unsafe' is destroyed here}}
}
}
(void)*p; // expected-note {{later used here}}
@@ -349,7 +349,7 @@ void multiple_expiry_of_same_loan(bool cond) {
if (cond) {
p = &unsafe; // expected-warning {{does not live long enough}}
if (cond)
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'unsafe' is destroyed here}}
}
}
(void)*p; // expected-note {{later used here}}
@@ -359,7 +359,7 @@ void multiple_expiry_of_same_loan(bool cond) {
if (cond) {
MyObj unsafe2;
p = &unsafe2; // expected-warning {{does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'unsafe2' is destroyed here}}
}
}
(void)*p; // expected-note {{later used here}}
@@ -370,7 +370,7 @@ void multiple_expiry_of_same_loan(bool cond) {
if (cond)
p = &unsafe; // expected-warning {{does not live long enough}}
if (cond)
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'unsafe' is destroyed here}}
}
(void)*p; // expected-note {{later used here}}
}
@@ -382,7 +382,7 @@ void switch_potential(int mode) {
case 1: {
MyObj temp;
p = &temp; // expected-warning {{local variable 'temp' does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp' is destroyed here}}
}
case 2: {
p = &safe; // This path is okay.
@@ -401,17 +401,17 @@ void switch_uaf(int mode) {
case 1: {
MyObj temp1;
p = &temp1; // expected-warning {{does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp1' is destroyed here}}
}
case 2: {
MyObj temp2;
p = &temp2; // expected-warning {{does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp2' is destroyed here}}
}
default: {
MyObj temp2;
p = &temp2; // expected-warning {{does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp2' is destroyed here}}
}
}
(void)*p; // expected-note 3 {{later used here}}
@@ -423,17 +423,17 @@ void switch_gsl(int mode) {
case 1: {
MyObj temp1;
v = temp1; // expected-warning {{local variable 'temp1' does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp1' is destroyed here}}
}
case 2: {
MyObj temp2;
v = temp2; // expected-warning {{local variable 'temp2' does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp2' is destroyed here}}
}
default: {
MyObj temp3;
v = temp3; // expected-warning {{local variable 'temp3' does not live long enough}}
- break; // expected-note {{destroyed here}}
+ break; // expected-note {{local variable 'temp3' is destroyed here}}
}
}
v.use(); // expected-note 3 {{later used here}}
@@ -451,7 +451,7 @@ void loan_from_previous_iteration(MyObj safe, bool condition) {
q = p;
(void)*p;
(void)*q; // expected-note {{later used here}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'x' is destroyed here}}
}
void trivial_int_uaf() {
@@ -459,7 +459,7 @@ void trivial_int_uaf() {
{
int b = 1;
a = &b; // expected-warning {{local variable 'b' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'b' is destroyed here}}
(void)*a; // expected-note {{later used here}}
}
@@ -468,7 +468,7 @@ void trivial_class_uaf() {
{
TriviallyDestructedClass s;
ptr = &s; // expected-warning {{local variable 's' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)ptr; // expected-note {{later used here}}
}
@@ -660,7 +660,7 @@ void test_view_pointer() {
{
View v;
vp = &v; // expected-warning {{local variable 'v' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'v' is destroyed here}}
vp->use(); // expected-note {{later used here}}
}
@@ -669,7 +669,7 @@ void test_view_double_pointer() {
{
View* vp = nullptr;
vpp = &vp; // expected-warning {{local variable 'vp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'vp' is destroyed here}}
(**vpp).use(); // expected-note {{later used here}}
}
@@ -698,7 +698,7 @@ void test_lifetimebound_multi_level() {
int*** ppp = &pp; // expected-warning {{local variable 'pp' does not live long enough}}
result = return_inner_ptr_addr(ppp); // expected-note {{local variable 'ppp' aliases the storage of local variable 'pp'}} \
// expected-note {{result of call to 'return_inner_ptr_addr' aliases the storage of local variable 'pp'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'pp' is destroyed here}}
(void)**result; // expected-note {{used here}}
}
@@ -731,7 +731,7 @@ MyObj* uaf_before_uar() {
{
MyObj local_obj;
p = &local_obj; // expected-warning {{local variable 'local_obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local_obj' is destroyed here}}
return p; // expected-note {{later used here}}
}
@@ -822,7 +822,7 @@ void lifetimebound_simple_function() {
MyObj obj;
v = Identity(obj); // expected-warning {{local variable 'obj' does not live long enough}} \
// expected-note {{result of call to 'Identity' aliases the storage of local variable 'obj'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -834,7 +834,8 @@ void lifetimebound_multiple_args_definite() {
// expected-note {{result of call to 'Choose' aliases the storage of local variable 'obj2'}}
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}}
+ } // expected-note {{local variable 'obj1' is destroyed here}} \
+ // expected-note {{local variable 'obj2' is destroyed here}}
v.use(); // expected-note 2 {{later used here}}
}
@@ -848,8 +849,8 @@ void lifetimebound_multiple_args_potential(bool cond) {
v = Choose(true,
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}}
+ } // expected-note {{local variable 'obj2' is destroyed here}}
+ } // expected-note {{local variable 'obj1' is destroyed here}}
v.use(); // expected-note 2 {{later used here}}
}
@@ -861,7 +862,7 @@ void lifetimebound_mixed_args() {
v = SelectFirst(obj1, // expected-warning {{local variable 'obj1' does not live long enough}} \
// expected-note {{result of call to 'SelectFirst' aliases the storage of local variable 'obj1'}}
obj2);
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj1' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -877,7 +878,7 @@ void lifetimebound_member_function() {
MyObj obj;
v = obj.getView(); // expected-warning {{local variable 'obj' does not live long enough}} \
// expected-note {{result of call to 'getView' aliases the storage of local variable 'obj'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -892,7 +893,7 @@ void lifetimebound_conversion_operator() {
{
LifetimeBoundConversionView obj;
v = obj; // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -902,7 +903,7 @@ void lifetimebound_chained_calls() {
MyObj obj;
v = Identity(Identity(Identity(obj))); // expected-warning {{local variable 'obj' does not live long enough}} \
// expected-note 3 {{result of call to 'Identity' aliases the storage of local variable 'obj'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -912,7 +913,7 @@ void lifetimebound_with_pointers() {
MyObj obj;
ptr = GetPointer(obj); // expected-warning {{local variable 'obj' does not live long enough}} \
// expected-note {{result of call to 'GetPointer' aliases the storage of local variable 'obj'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)*ptr; // expected-note {{later used here}}
}
@@ -922,7 +923,7 @@ void chained_assignment_lifetimebound_call() {
MyObj s;
p = Identity(obj = &s); // expected-warning {{does not live long enough}} \
// expected-note {{result of call to 'Identity' aliases the storage of local variable 's'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -942,7 +943,7 @@ void lifetimebound_partial_safety(bool cond) {
v = Choose(true,
safe_obj,
temp_obj); // expected-warning {{local variable 'temp_obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp_obj' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -956,7 +957,7 @@ void lifetimebound_return_reference() {
const MyObj& ref = GetObject(temp_v); // expected-note {{local variable 'temp_v' aliases the storage of local variable 'obj'}} \
// expected-note {{result of call to 'GetObject' aliases the storage of local variable 'obj'}}
ptr = &ref;
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)*ptr; // expected-note {{later used here}}
}
@@ -973,7 +974,7 @@ void lifetimebound_ctor() {
{
MyObj obj;
v = obj; // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)v; // expected-note {{later used here}}
}
@@ -982,7 +983,7 @@ void lifetimebound_ctor_functional_cast() {
{
MyObj obj;
v = LifetimeBoundCtor(obj); // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)v; // expected-note {{later used here}}
}
@@ -991,7 +992,7 @@ void lifetimebound_ctor_c_style_cast() {
{
MyObj obj;
v = (LifetimeBoundCtor)(obj); // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)v; // expected-note {{later used here}}
}
@@ -1000,7 +1001,7 @@ void lifetimebound_ctor_static_cast() {
{
MyObj obj;
v = static_cast<LifetimeBoundCtor>(obj); // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)v; // expected-note {{later used here}}
}
@@ -1010,7 +1011,7 @@ void lifetimebound_make_unique() {
MyObj obj;
ptr = std::make_unique<LifetimeBoundCtor>(obj); // tu-warning {{local variable 'obj' does not live long enough}} \
// tu-note {{result of call to 'make_unique<LifetimeBoundCtor, MyObj &>' aliases the storage of local variable 'obj'}}
- } // tu-note {{destroyed here}}
+ } // tu-note {{local variable 'obj' is destroyed here}}
(void)ptr; // tu-note {{later used here}}
}
@@ -1026,7 +1027,7 @@ void non_lifetimebound_make_unique() {
void lifetimebound_make_unique_temp() {
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 {{temporary object is destroyed here}} \
// tu-note {{result of call to 'make_unique<LifetimeBoundCtor, MyObj>' aliases the storage of temporary object}}
(void)ptr; // tu-note {{later used here}}
}
@@ -1066,7 +1067,7 @@ void lifetimebound_make_unique_multi_params() {
MyObj obj_short;
ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_short, obj_long); // tu-warning {{local variable 'obj_short' does not live long enough}} \
// tu-note {{result of call to 'make_unique<MultiLifetimeBoundCtor, MyObj &, MyObj &>' aliases the storage of local variable 'obj_short'}}
- } // tu-note {{destroyed here}}
+ } // tu-note {{local variable 'obj_short' is destroyed here}}
(void)ptr; // tu-note {{later used here}}
}
@@ -1077,7 +1078,7 @@ void lifetimebound_make_unique_multi_params2() {
MyObj obj_short;
ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_long, obj_short, 1); // tu-warning {{local variable 'obj_short' does not live long enough}} \
// tu-note {{result of call to 'make_unique<MultiLifetimeBoundCtor, MyObj &, MyObj &, int>' aliases the storage of local variable 'obj_short'}}
- } // tu-note {{destroyed here}}
+ } // tu-note {{local variable 'obj_short' is destroyed here}}
(void)ptr; // tu-note {{later used here}}
}
@@ -1098,7 +1099,7 @@ void lifetimebound_make_unique_multi_params3_1() {
MyObj obj_short;
ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_short, obj_long, 1.0); // tu-warning {{local variable 'obj_short' does not live long enough}} \
// tu-note {{result of call to 'make_unique<MultiLifetimeBoundCtor, MyObj &, MyObj &, double>' aliases the storage of local variable 'obj_short'}}
- } // tu-note {{destroyed here}}
+ } // tu-note {{local variable 'obj_short' is destroyed here}}
(void)ptr; // tu-note {{later used here}}
}
@@ -1109,7 +1110,7 @@ void lifetimebound_make_unique_multi_params3_2() {
MyObj obj_short;
ptr = std::make_unique<MultiLifetimeBoundCtor>(obj_long, obj_short, 1.0); // tu-warning {{local variable 'obj_short' does not live long enough}} \
// tu-note {{result of call to 'make_unique<MultiLifetimeBoundCtor, MyObj &, MyObj &, double>' aliases the storage of local variable 'obj_short'}}
- } // tu-note {{destroyed here}}
+ } // tu-note {{local variable 'obj_short' is destroyed here}}
(void)ptr; // tu-note {{later used here}}
}
@@ -1186,7 +1187,7 @@ void conditional_operator_one_unsafe_branch(bool cond) {
MyObj temp;
p = cond ? &temp // expected-warning {{local variable 'temp' does not live long enough}}
: &safe;
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
// This is not a use-after-free for any value of `cond` but the analysis
// cannot reason this and marks the above as a false positive. This
@@ -1202,7 +1203,7 @@ void conditional_operator_two_unsafe_branches(bool cond) {
MyObj a, b;
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}}
+ } // expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note 2 {{later used here}}
}
@@ -1214,7 +1215,7 @@ void conditional_operator_nested(bool cond) {
: &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}}
+ } // expected-note {{local variable 'a' is destroyed here}} expected-note {{local variable 'd' is destroyed here}} expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'c' is destroyed here}}
(void)*p; // expected-note 4 {{later used here}}
}
@@ -1224,7 +1225,7 @@ void conditional_operator_lifetimebound(bool cond) {
MyObj a, b;
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}}
+ } // expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note 2 {{later used here}}
}
@@ -1234,7 +1235,7 @@ void conditional_operator_lifetimebound_nested(bool cond) {
MyObj a, b;
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}}
+ } // expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note 2 {{later used here}}
}
@@ -1246,7 +1247,7 @@ void conditional_operator_lifetimebound_nested_deep(bool cond) {
: &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}}
+ } // expected-note {{local variable 'a' is destroyed here}} expected-note {{local variable 'd' is destroyed here}} expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'c' is destroyed here}}
(void)*p; // expected-note 4 {{later used here}}
}
@@ -1257,7 +1258,7 @@ void comma_use_after_scope() {
{
MyObj temp;
p = (side(), &temp); // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1266,7 +1267,7 @@ void comma_nested() {
{
MyObj temp;
p = (side(), (side(), &temp)); // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1277,7 +1278,7 @@ void comma_masked_by_conditional(bool cond) {
{
MyObj temp;
p = cond ? keep : (side(), &temp); // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1293,7 +1294,7 @@ void binary_conditional_false_unsafe(MyObj* in) {
{
MyObj temp;
p = in ?: &temp; // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1303,7 +1304,7 @@ void binary_conditional_common_unsafe(MyObj* fallback) {
MyObj temp;
MyObj* t = &temp; // expected-warning {{local variable 'temp' does not live long enough}}
p = t ?: fallback;
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1318,7 +1319,7 @@ void binary_conditional_nested(MyObj* a, MyObj* b) {
{
MyObj temp;
p = a ?: b ?: &temp; // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1329,14 +1330,14 @@ void binary_conditional_masked_by_conditional(bool cond, MyObj* in) {
{
MyObj temp;
p = cond ? keep : (in ?: &temp); // expected-warning {{local variable 'temp' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'temp' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
void binary_conditional_use_after_free(int* in) {
int* h = new int; // expected-warning {{allocated object does not live long enough}}
int* p = in ?: h;
- delete h; // expected-note {{freed here}}
+ delete h; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1377,7 +1378,7 @@ void simpleparen() {
MyObj a;
MyObj* b = &a; // expected-warning {{local variable 'a' does not live long enough}}
p = (((b)));
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1386,14 +1387,14 @@ void parentheses(bool cond) {
{
MyObj a;
p = &((((a)))); // expected-warning {{local variable 'a' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
{
MyObj a;
p = ((GetPointer((a)))); // expected-warning {{local variable 'a' does not live long enough}} \
// expected-note {{result of call to 'GetPointer' aliases the storage of local variable 'a'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
{
@@ -1402,14 +1403,14 @@ void parentheses(bool cond) {
: 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}}
+ } // expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'c' is destroyed here}} expected-note {{local variable 'a' is destroyed here}} expected-note {{local variable 'd' is destroyed here}}
(void)*p; // expected-note 4 {{later used here}}
{
MyObj a, b, c, d;
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}}
+ } // expected-note {{local variable 'd' is destroyed here}} expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'c' is destroyed here}} expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note 4 {{later used here}}
}
@@ -1417,13 +1418,13 @@ void parentheses(bool cond) {
void use_temporary_after_destruction() {
View a;
a = non_trivially_destructed_temporary(); // expected-warning {{temporary object does not live long enough}} \
- expected-note {{destroyed here}}
+ expected-note {{temporary object is 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 {{temporary object does not live long enough}} \
- expected-note {{destroyed here}} \
+ expected-note {{temporary object is destroyed here}} \
expected-note {{result of call to 'construct_view' aliases the storage of temporary object}}
use(a); // expected-note {{later used here}}
}
@@ -1431,7 +1432,7 @@ void passing_temporary_to_lifetime_bound_function() {
void use_trivial_temporary_after_destruction() {
View a;
a = trivially_destructed_temporary(); // expected-warning {{temporary object does not live long enough}} \
- expected-note {{destroyed here}}
+ expected-note {{temporary object is destroyed here}}
use(a); // expected-note {{later used here}}
}
@@ -1467,7 +1468,7 @@ namespace FullExprCleanupLoc {
void var_initializer() {
View v = non_trivially_destructed_temporary() // expected-warning {{temporary object does not live long enough}} \
// expected-note {{result of call to 'getView' aliases the storage of temporary object}}
- .getView(); // expected-note {{destroyed here}}
+ .getView(); // expected-note {{temporary object is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -1475,7 +1476,7 @@ void expr_statement() {
View v;
v = non_trivially_destructed_temporary() // expected-warning {{temporary object does not live long enough}} \
// expected-note {{result of call to 'getView' aliases the storage of temporary object}}
- .getView(); // expected-note {{destroyed here}}
+ .getView(); // expected-note {{temporary object is destroyed here}}
v.use(); // expected-note {{later used here}}
}
} // namespace FullExprCleanupLoc
@@ -1520,7 +1521,7 @@ void foobar() {
view = string_or. // expected-warning {{local variable 'string_or' does not live long enough}} \
// expected-note {{result of call to 'value' aliases the storage of local variable 'string_or'}}
value();
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'string_or' is destroyed here}}
(void)view; // expected-note {{later used here}}
}
} // namespace GH162834
@@ -1541,7 +1542,7 @@ void range_based_for_use_after_scope() {
for (const MyObj &o : s) { // expected-warning {{local variable 's' does not live long enough}}
v = o;
}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -1558,7 +1559,7 @@ void range_based_for_not_reference() {
View v;
{
MyObjStorage s;
- for (MyObj o : s) { // expected-note {{destroyed here}}
+ for (MyObj o : s) { // expected-note {{local variable 'o' is destroyed here}}
v = o; // expected-warning {{local variable 'o' does not live long enough}}
}
}
@@ -1594,7 +1595,7 @@ void test_user_defined_deref_uaf() {
SmartPtr<MyObj> smart_ptr(&obj);
p = &(*smart_ptr); // expected-warning {{local variable 'smart_ptr' does not live long enough}} \
// expected-note {{expression aliases the storage of local variable 'smart_ptr'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'smart_ptr' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1612,7 +1613,7 @@ void test_user_defined_deref_with_view() {
SmartPtr<MyObj> smart_ptr(&obj);
v = *smart_ptr; // expected-warning {{local variable 'smart_ptr' does not live long enough}} \
// expected-note {{expression aliases the storage of local variable 'smart_ptr'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'smart_ptr' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -1623,7 +1624,7 @@ void test_user_defined_deref_arrow() {
SmartPtr<MyObj> smart_ptr(&obj);
p = smart_ptr.operator->(); // expected-warning {{local variable 'smart_ptr' does not live long enough}} \
// expected-note {{expression aliases the storage of local variable 'smart_ptr'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'smart_ptr' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1634,7 +1635,7 @@ void test_user_defined_deref_chained() {
SmartPtr<SmartPtr<MyObj>> double_ptr;
p = &(**double_ptr); // expected-warning {{local variable 'double_ptr' does not live long enough}} \
// expected-note 2 {{expression aliases the storage of local variable 'double_ptr'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'double_ptr' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -1786,7 +1787,7 @@ void strict_warn_on_move() {
MyObj a;
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}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)v; // expected-note {{later used here}}
}
@@ -1799,7 +1800,7 @@ void flow_sensitive(bool c) {
return;
}
v = a; // expected-warning {{local variable 'a' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)v; // expected-note {{later used here}}
}
@@ -1811,7 +1812,7 @@ void detect_conditional(bool cond) {
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}}
+ } // expected-note {{local variable 'b' is destroyed here}} expected-note {{local variable 'a' is destroyed here}}
(void)v; // expected-note 2 {{later used here}}
}
@@ -1821,7 +1822,7 @@ void wrong_use_of_move_is_permissive() {
MyObj a;
v = std::move(a); // expected-warning {{local variable 'a' does not live long enough}} \
// expected-note {{result of call to 'move<MyObj &>' aliases the storage of local variable 'a'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)v; // expected-note {{later used here}}
const int* p;
{
@@ -1829,7 +1830,7 @@ void wrong_use_of_move_is_permissive() {
p = std::move(a).getData(); // expected-warning {{local variable 'a' does not live long enough}} \
// expected-note {{result of call to 'move<MyObj &>' aliases the storage of local variable 'a'}} \
// expected-note {{result of call to 'getData' aliases the storage of local variable 'a'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)p; // expected-note {{later used here}}
}
@@ -1842,7 +1843,7 @@ void test_release_no_uaf() {
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}} \
// expected-note {{result of call to 'get' aliases the storage of local variable 'p'}}
take(p.release()); // expected-note {{potentially moved here}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'p' is destroyed here}}
(void)*r; // expected-note {{later used here}}
}
} // namespace strict_warn_on_move
@@ -1865,10 +1866,10 @@ void bar() {
x = s.x(); // expected-warning {{local variable 's' does not live long enough}} \
// expected-note {{result of call to 'x' aliases the storage of local variable 's'}}
View y = S().x(); // expected-warning {{temporary object does not live long enough}} \
- expected-note {{destroyed here}} \
+ expected-note {{temporary object is destroyed here}} \
expected-note {{result of call to 'x' aliases the storage of temporary object}}
(void)y; // expected-note {{used here}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)x; // expected-note {{used here}}
}
}
@@ -1954,11 +1955,11 @@ 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 {{temporary object does not live long enough}} expected-note {{destroyed here}} \
+ const std::string& x = S().x(); // expected-warning {{temporary object does not live long enough}} expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'x' aliases the storage of temporary object}}
(void)x; // expected-note {{later used here}}
- const std::string& y = identity(S().x()); // expected-warning {{temporary object does not live long enough}} expected-note {{destroyed here}} \
+ const std::string& y = identity(S().x()); // expected-warning {{temporary object does not live long enough}} expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'x' aliases the storage of temporary object}} \
// expected-note {{result of call to 'identity' aliases the storage of temporary object}}
(void)y; // expected-note {{later used here}}
@@ -1969,20 +1970,20 @@ void test_temporary() {
const std::string& zz = s.x(); // expected-warning {{local variable 's' does not live long enough}} \
// expected-note {{result of call to 'x' aliases the storage of local variable 's'}}
z = zz; // expected-note {{expression aliases the storage of local variable 's'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)z; // expected-note {{later used here}}
}
void test_lifetime_extension_ok() {
const S& x = S();
(void)x;
- const S& y = identity(S()); // expected-warning {{temporary object does not live long enough}} expected-note {{destroyed here}} \
+ const S& y = identity(S()); // expected-warning {{temporary object does not live long enough}} expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'identity' 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 {{temporary object does not live long enough}} expected-note {{destroyed here}} \
+ const std::string& x = S().x(); // expected-warning {{temporary object does not live long enough}} expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'x' aliases the storage of temporary object}}
return x; // expected-note {{later used here}}
}
@@ -2002,7 +2003,7 @@ void uaf() {
S* p = &str; // expected-warning {{local variable 'str' does not live long enough}}
view = p->s; // expected-note {{local variable 'p' aliases the storage of local variable 'str'}} \
// expected-note {{expression aliases the storage of local variable 'str'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'str' is destroyed here}}
(void)view; // expected-note {{later used here}}
}
@@ -2029,7 +2030,7 @@ void uaf_union() {
U* up = &u; // expected-warning {{local variable 'u' does not live long enough}}
view = up->s; // expected-note {{local variable 'up' aliases the storage of local variable 'u'}} \
// expected-note {{expression aliases the storage of local variable 'u'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'u' is destroyed here}}
(void)view; // expected-note {{later used here}}
}
@@ -2046,7 +2047,7 @@ void uaf_anonymous_union() {
AnonymousUnion au;
AnonymousUnion* up = &au; // expected-warning {{local variable 'au' does not live long enough}}
ip = &up->x; // expected-note {{local variable 'up' aliases the storage of local variable 'au'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'au' is destroyed here}}
(void)ip; // expected-note {{later used here}}
}
@@ -2103,11 +2104,11 @@ const T* MemberFuncsTpl<T>::memberC(const T& x [[clang::lifetimebound]]) {
void test() {
MemberFuncsTpl<MyObj> mtf;
- const MyObj* pTMA = mtf.memberA(MyObj()); // expected-warning {{temporary object does not live long enough}} // expected-note {{destroyed here}} \
+ const MyObj* pTMA = mtf.memberA(MyObj()); // expected-warning {{temporary object does not live long enough}} // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'memberA' 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}} \
+ const MyObj* pTMB = mtf.memberB(MyObj()); // tu-warning {{temporary object does not live long enough}} // tu-note {{temporary object is destroyed here}} \
// tu-note {{result of call to 'memberB' 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}} \
+ const MyObj* pTMC = mtf.memberC(MyObj()); // expected-warning {{temporary object does not live long enough}} // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'memberC' aliases the storage of temporary object}}
(void)pTMA; // expected-note {{later used here}}
(void)pTMB; // tu-note {{later used here}}
@@ -2146,7 +2147,7 @@ void test_optional_arrow() {
p = opt->data(); // expected-warning {{local variable 'opt' does not live long enough}} \
// expected-note {{expression aliases the storage of local variable 'opt'}} \
// expected-note {{result of call to 'data' aliases the storage of local variable 'opt'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'opt' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -2157,7 +2158,7 @@ void test_optional_arrow_lifetimebound() {
v = opt->getView(); // expected-warning {{local variable 'opt' does not live long enough}} \
// expected-note {{expression aliases the storage of local variable 'opt'}} \
// expected-note {{result of call to 'getView' aliases the storage of local variable 'opt'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'opt' is destroyed here}}
v.use(); // expected-note {{later used here}}
}
@@ -2168,7 +2169,7 @@ void test_unique_ptr_arrow() {
p = up->data(); // expected-warning {{local variable 'up' does not live long enough}} \
// expected-note {{expression aliases the storage of local variable 'up'}} \
// expected-note {{result of call to 'data' aliases the storage of local variable 'up'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'up' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -2362,7 +2363,7 @@ void multi_level_pointer_in_loop() {
pp = &p;
}
(void)**pp; // expected-note {{later used here}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
}
void outer_pointer_outlives_inner_pointee() {
@@ -2371,7 +2372,7 @@ void outer_pointer_outlives_inner_pointee() {
for (int i = 0; i < 10; ++i) {
MyObj obj;
view = &obj; // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)*view; // expected-note {{later used here}}
}
@@ -2384,7 +2385,7 @@ void element_use_after_scope() {
{
int a[10]{};
p = &a[2]; // expected-warning {{local variable 'a' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -2416,7 +2417,7 @@ void multidimensional_use_after_scope() {
{
int a[3][4]{};
p = &a[1][2]; // expected-warning {{local variable 'a' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -2429,7 +2430,7 @@ void member_array_element_use_after_scope() {
{
S s;
p = &s.arr[0]; // expected-warning {{local variable 's' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 's' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -2438,7 +2439,7 @@ void array_of_pointers_use_after_scope() {
{
int* a[10]{};
p = a; // expected-warning {{local variable 'a' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -2447,7 +2448,7 @@ void reversed_subscript_use_after_scope() {
{
int a[10]{};
p = &(0[a]); // expected-warning {{local variable 'a' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -2475,7 +2476,7 @@ void pointer_arithmetic_use_after_scope() {
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}}
+ } // expected-note 3 {{local variable 'a' is destroyed here}}
(void)*p; // expected-note {{later used here}}
(void)*p2; // expected-note {{later used here}}
(void)*p3; // expected-note {{later used here}}
@@ -2521,7 +2522,7 @@ void indexing_with_static_operator() {
S()(1, 2);
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}}
+ 3); // expected-warning {{temporary object does not live long enough}} expected-note 2 {{temporary object is destroyed here}}
(void)x; // expected-note 2 {{later used here}}
@@ -2544,14 +2545,14 @@ S getS(const std::string &s [[clang::lifetimebound]]);
void from_free_function() {
S s = getS(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'getS' aliases the storage of temporary object}}
use(s); // expected-note {{later used here}}
}
void from_constructor() {
S s(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}}
+ // expected-note {{temporary object is destroyed here}}
use(s); // expected-note {{later used here}}
}
@@ -2564,14 +2565,14 @@ struct Factory {
void from_method() {
Factory f;
S s = f.make(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'make' 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 {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'create' aliases the storage of temporary object}}
use(s); // expected-note {{later used here}}
}
@@ -2582,7 +2583,7 @@ void from_lifetimebound_this_method() {
Factory f;
value = f.makeThis(); // expected-warning {{local variable 'f' does not live long enough}} \
// expected-note {{result of call to 'makeThis' aliases the storage of local variable 'f'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'f' is destroyed here}}
use(value); // expected-note {{later used here}}
}
@@ -2592,7 +2593,7 @@ void across_scope() {
std::string str{"abc"};
s = getS(str); // expected-warning {{local variable 'str' does not live long enough}} \
// expected-note {{result of call to 'getS' aliases the storage of local variable 'str'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'str' is destroyed here}}
use(s); // expected-note {{later used here}}
}
@@ -2616,7 +2617,7 @@ void assignment_propagation() {
a = getS(str); // expected-warning {{local variable 'str' does not live long enough}} \
// expected-note {{result of call to 'getS' aliases the storage of local variable 'str'}}
b = a; // expected-note {{local variable 'a' aliases the storage of local variable 'str'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'str' is destroyed here}}
use(b); // expected-note {{later used here}}
}
@@ -2628,7 +2629,7 @@ void chained_defaulted_assignment_propagation() {
// expected-note {{result of call to 'getS' aliases the storage of local variable 'str'}}
c = b = a; // expected-note {{local variable 'a' aliases the storage of local variable 'str'}}\
// expected-note {{expression aliases the storage of local variable 'str'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'str' is destroyed here}}
use(c); // expected-note {{later used here}}
}
@@ -2641,7 +2642,7 @@ void no_annotation() {
void mix_annotated_and_not() {
S s1 = getS(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'getS' aliases the storage of temporary object}}
S s2 = getSNoAnnotation(std::string("temp"));
use(s1); // expected-note {{later used here}}
@@ -2655,7 +2656,7 @@ S multiple_lifetimebound_params() {
S s = getS2(str, std::string("temp")); // expected-warning {{stack memory associated with local variable 'str' is returned}} \
// expected-warning {{temporary object does not live long enough}} \
// expected-note {{result of call to 'getS2' aliases the storage of temporary object}} \
- // expected-note {{destroyed here}}
+ // expected-note {{temporary object is destroyed here}}
return s; // expected-note {{returned here}} \
// expected-note {{later used here}}
}
@@ -2674,7 +2675,7 @@ T make(const std::string &s [[clang::lifetimebound]]);
void from_template_instantiation() {
S s = make<S>(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'make<track_origins_for_lifetimebound_record_type::S>' aliases the storage of temporary object}}
use(s); // expected-note {{later used here}}
}
@@ -2738,7 +2739,7 @@ SAlias getSAlias(const std::string &s [[clang::lifetimebound]]);
void from_typedef_return() {
SAlias s = getSAlias(std::string("temp")); // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'getSAlias' aliases the storage of temporary object}}
use(s); // expected-note {{later used here}}
}
@@ -2813,7 +2814,7 @@ 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 {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}} \
+ // expected-note {{temporary object is destroyed here}} \
// expected-note {{result of call to 'getUniqueS' aliases the storage of temporary object}}
(void)ptr; // expected-note {{later used here}}
}
@@ -2832,7 +2833,7 @@ void owner_outlives_lifetimebound_source() {
std::string local;
ups = getUniqueS(local); // expected-warning {{local variable 'local' does not live long enough}} \
// expected-note {{result of call to 'getUniqueS' aliases the storage of local variable 'local'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)ups; // expected-note {{later used here}}
}
@@ -2855,7 +2856,7 @@ void local_pointer() {
{
int v;
p = Pointer(v); // expected-warning {{local variable 'v' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'v' is destroyed here}}
use(*p); // expected-note {{later used here}}
}
@@ -2868,7 +2869,7 @@ void nested_local_pointer() {
p = Pointer(v); // expected-warning {{local variable 'v' does not live long enough}}
pp = Pointer(p); // expected-note {{local variable 'p' aliases the storage of local variable 'v'}}
ppp = Pointer(pp); // expected-note {{local variable 'pp' aliases the storage of local variable 'v'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'v' is destroyed here}}
use(***ppp); // expected-note {{later used here}}
}
@@ -2965,50 +2966,50 @@ void new_view_from_dead_scope() {
{
MyObj obj;
p = new View(obj); // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
p->use(); // expected-note {{later used here}}
}
void new_int_basic() {
int *p = new int; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
void new_int_parens() {
int *p = new int(); // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
void new_int_braces() {
int *p = new int{}; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
void new_int_aligned() {
int *p = new (std::align_val_t(sizeof(int))) int{}; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
void new_int_nothrow() {
int *p = new (std::nothrow) int{}; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
void new_int_aligned_nothrow() {
int *p = new (std::align_val_t(sizeof(int)), std::nothrow) int{}; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
void conditional_delete(bool cond) {
int *p1 = new int; // expected-warning {{allocated object does not live long enough}}
int *p2 = new int; // expected-warning {{allocated object does not live long enough}}
- delete (cond ? p1 : p2); // expected-note 2 {{freed here}}
+ delete (cond ? p1 : p2); // expected-note 2 {{allocated object is freed here}}
(void)*p1; // expected-note {{later used here}}
(void)*p2; // expected-note {{later used here}}
}
@@ -3018,7 +3019,7 @@ int* foo(int* x [[clang::lifetimebound]], int* y [[clang::lifetimebound]]);
void delete_returned_from_call() {
int* x = new int(1); // expected-warning {{allocated object does not live long enough}}
int* y = new int(2); // expected-warning {{allocated object does not live long enough}}
- delete foo(x, y); // expected-note 2 {{freed here}}
+ delete foo(x, y); // expected-note 2 {{allocated object is freed here}}
(void)x; // expected-note {{later used here}}
(void)y; // expected-note {{later used here}}
}
@@ -3029,7 +3030,7 @@ void new_pointer_from_pointer() {
MyObj obj;
MyObj *q = &obj; // expected-warning {{local variable 'obj' does not live long enough}}
p = new MyObj *(q); // expected-note {{local variable 'q' aliases the storage of local variable 'obj'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)**p; // expected-note {{later used here}}
}
@@ -3038,7 +3039,7 @@ void new_pointer_from_dead_object() {
{
MyObj obj;
p = new MyObj *(&obj); // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)**p; // expected-note {{later used here}}
}
@@ -3052,25 +3053,25 @@ void new_multiview_from_mixed_scope() {
{
MyObj obj2;
p = new MultiView(obj1, obj2); // expected-warning {{local variable 'obj2' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj2' is destroyed here}}
(void)p; // expected-note {{later used here}}
}
void new_array_basic() {
int *p = new int[2]; // expected-warning {{allocated object does not live long enough}}
- delete[] p; // expected-note {{freed here}}
+ delete[] p; // expected-note {{allocated object is freed here}}
(void)p[0]; // expected-note {{later used here}}
}
void new_array_parens() {
int *p = new int[2](); // expected-warning {{allocated object does not live long enough}}
- delete[] p; // expected-note {{freed here}}
+ delete[] p; // expected-note {{allocated object is freed here}}
(void)p[0]; // expected-note {{later used here}}
}
void new_array_braces() {
int *p = new int[2]{}; // expected-warning {{allocated object does not live long enough}}
- delete[] p; // expected-note {{freed here}}
+ delete[] p; // expected-note {{allocated object is freed here}}
(void)p[0]; // expected-note {{later used here}}
}
@@ -3105,26 +3106,26 @@ void pointer_array_field_sensitivity() {
void delete_direct_use_after_free() {
MyObj *p = new MyObj; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)p->id; // expected-note {{later used here}}
}
void delete_alias_use_after_free() {
MyObj *p = new MyObj; // expected-warning {{allocated object does not live long enough}}
MyObj *q = p;
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)q->id; // expected-note {{later used here}}
}
void delete_pointer_propagation_use_after_free() {
MyObj *p = new MyObj; // expected-warning {{allocated object does not live long enough}}
MyObj **pp = &p;
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)(*pp)->id; // expected-note {{later used here}}
}
void delete_param_pointer(int* x) { // expected-warning {{parameter 'x' does not live long enough}}
- delete x; // expected-note {{freed here}}
+ delete x; // expected-note {{parameter 'x' is freed here}}
(void)x; // expected-note {{later used here}}
}
@@ -3139,7 +3140,7 @@ struct S {
void use_inner_origin_after_delete(MyObj* obj) { // expected-warning {{parameter 'obj' does not live long enough}}
int* p = &obj->id;
- delete obj; // expected-note {{freed here}}
+ delete obj; // expected-note {{parameter 'obj' is freed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -3160,7 +3161,7 @@ struct ClassSpecificDelete {
void class_specific_operator_delete_use_after_free() {
ClassSpecificDelete *p = new ClassSpecificDelete; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)p->X; // expected-note {{later used here}}
}
@@ -3172,7 +3173,7 @@ struct ClassSpecificNew {
void class_specific_operator_new_use_after_free() {
ClassSpecificNew *p = new ClassSpecificNew; // expected-warning {{allocated object does not live long enough}}
- delete p; // expected-note {{freed here}}
+ delete p; // expected-note {{allocated object is freed here}}
(void)p->X; // expected-note {{later used here}}
}
@@ -3190,14 +3191,14 @@ void delete_through_pointer_field() {
void delete_stack_object() {
MyObj obj;
MyObj* p = &obj; // expected-warning {{local variable 'obj' does not live long enough}}
- delete &obj; // expected-note {{freed here}}
+ delete &obj; // expected-note {{local variable 'obj' is freed here}}
(void)p->id; // expected-note {{later used here}}
}
void delete_stack_object_int() {
int obj;
int* p = &obj; // expected-warning {{local variable 'obj' does not live long enough}}
- delete &obj; // expected-note {{freed here}}
+ delete &obj; // expected-note {{local variable 'obj' is freed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -3215,7 +3216,7 @@ void placement_new_int_basic() {
{
int storage;
p = new (&storage) int; // expected-warning {{local variable 'storage' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'storage' is destroyed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -3225,7 +3226,7 @@ void placement_new_view_from_dead_scope() {
{
MyObj obj;
p = new (&storage) View(obj); // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
p->use(); // expected-note {{later used here}}
}
@@ -3235,7 +3236,7 @@ void placement_new_pointer_from_dead_object() {
{
MyObj obj;
p = new (&slot) MyObj *(&obj); // expected-warning {{local variable 'obj' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'obj' is destroyed here}}
(void)**p; // expected-note {{later used here}}
}
@@ -3244,7 +3245,7 @@ void placement_new_array_basic() {
{
int storage[2];
p = new (&storage) int[2]; // expected-warning {{local variable 'storage' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'storage' is destroyed here}}
(void)p[0]; // expected-note {{later used here}}
}
@@ -3253,14 +3254,14 @@ void placement_new_array_braces() {
{
int storage[2];
p = new (&storage) int[2]{}; // expected-warning {{local variable 'storage' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'storage' is destroyed here}}
(void)p[0]; // expected-note {{later used here}}
}
void placement_new_heap_then_delete_use_after_free() {
int *storage = new int(7); // expected-warning {{allocated object does not live long enough}}
int *p = new (storage) int(42);
- delete storage; // expected-note {{freed here}}
+ delete storage; // expected-note {{allocated object is freed here}}
(void)*p; // expected-note {{later used here}}
}
@@ -3308,7 +3309,7 @@ void placement_new_delete_result_of_lifetimebound_call() {
int *y = new int(2); // expected-warning {{allocated object does not live long enough}}
int *slot = nullptr;
int **p = new (&slot) int *(foo(x, y));
- delete foo(x, y); // expected-note 2 {{freed here}}
+ delete foo(x, y); // expected-note 2 {{allocated object is freed here}}
(void)**p; // expected-note 2 {{later used here}}
}
@@ -3459,7 +3460,7 @@ struct S {
{
int num;
this->p_ = # // expected-warning {{local variable 'num' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'num' is destroyed here}}
bar(); // expected-note {{later used here}}
this->p_ = &GLOBAL_INT;
}
@@ -3477,7 +3478,7 @@ struct T {
std::string_view v;
void bar();
void foo() {
- v = std::string("tmp"); // expected-warning {{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 {{temporary object is destroyed here}}
bar(); // expected-note {{later used here}}
}
};
@@ -3499,7 +3500,7 @@ struct S2 : S {
{
int num;
this->p_ = # // expected-warning {{local variable 'num' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'num' is destroyed here}}
bar(); // expected-note {{later used here}}
this->p_ = &GLOBAL_INT;
}
@@ -3507,7 +3508,7 @@ struct S2 : S {
{
int num;
this->p_ = # // expected-warning {{local variable 'num' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'num' is destroyed here}}
bar2(); // expected-note {{later used here}}
this->p_ = nullptr;
}
@@ -3625,7 +3626,7 @@ void uaf_via_lifetimebound() {
int local;
f = capture_lifetimebound_param(local); // expected-warning {{local variable 'local' does not live long enough}} \
// expected-note {{result of call to 'capture_lifetimebound_param' aliases the storage of local variable 'local'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)f; // expected-note {{later used here}}
}
@@ -3644,7 +3645,7 @@ struct [[gsl::Pointer]] function_ref {
// avoid this warning for non-capturing lambdas.
void assign_non_capturing_to_function_ref(function_ref &r) {
r = []() {}; // expected-warning {{temporary object does not live long enough}} \
- // expected-note {{destroyed here}}
+ // expected-note {{temporary object is destroyed here}}
(void)r; // expected-note {{later used here}}
}
@@ -3689,7 +3690,7 @@ void deref_use_after_scope() {
optional<MyObj> opt;
p = &*opt; // expected-warning {{local variable 'opt' does not live long enough}} \
// expected-note {{expression aliases the storage of local variable 'opt'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'opt' is destroyed here}}
(void)p->id; // expected-note {{later used here}}
}
@@ -3741,7 +3742,7 @@ void use_after_free_capture_by() {
{
MyObj a;
setCaptureBy(res, a); // expected-warning {{local variable 'a' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'a' is destroyed here}}
(void)res; // expected-note {{later used here}}
}
@@ -3759,7 +3760,7 @@ void transitive_capture() {
MyObj local;
setCaptureBy(v1, local); // expected-warning {{local variable 'local' does not live long enough}}
setCaptureBy(v2, v1); // expected-note {{local variable 'v1' aliases the storage of local variable 'local'}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)v2; // expected-note {{later used here}}
}
@@ -3770,7 +3771,7 @@ void test_reference_to_view() {
{
MyObj local;
set1(v, local); // expected-warning {{local variable 'local' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)v; // expected-note {{later used here}}
}
@@ -3801,7 +3802,7 @@ void test_reference_to_pointer() {
{
MyObj local;
set3(ptr, local); // expected-warning {{local variable 'local' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)ptr; // expected-note {{later used here}}
}
@@ -3815,7 +3816,7 @@ void member_capture() {
{
MyObj local;
c.set(local); // expected-warning {{local variable 'local' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)c.stored; // expected-note {{later used here}}
}
@@ -3844,7 +3845,7 @@ void multiple_captures() {
{
MyObj val2;
captureTwo(res, val1, val2); // expected-warning {{local variable 'val2' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'val2' is destroyed here}}
(void)res; // expected-note {{later used here}}
}
@@ -3854,7 +3855,7 @@ void multiple_local_captures() {
MyObj val1;
MyObj val2;
captureTwo(res, val1, val2); // expected-warning {{local variable 'val1' does not live long enough}} // expected-warning {{local variable 'val2' does not live long enough}}
- } // expected-note 2 {{destroyed here}}
+ } // expected-note {{local variable 'val2' is destroyed here}} expected-note {{local variable 'val1' is destroyed here}}
(void)res; // expected-note 2 {{later used here}}
}
@@ -3866,7 +3867,7 @@ void captured_by_multiple_params() {
{
MyObj local;
captureIntoTwo(v1, v2, local); // expected-warning {{local variable 'local' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)v1; // expected-note {{later used here}}
}
@@ -3875,7 +3876,7 @@ void captured_by_multiple_params_2() {
{
MyObj local;
captureIntoTwo(v1, v2, local); // expected-warning {{local variable 'local' does not live long enough}}
- } // expected-note {{destroyed here}}
+ } // expected-note {{local variable 'local' is destroyed here}}
(void)v2; // expected-note {{later used here}}
}
@@ -3886,7 +3887,7 @@ void capturing_multiple_locals() {
setCaptureBy(v, local1); // expected-warning{{local variable 'local1' does not live long enough}}
MyObj local2;
setCaptureBy(v, local2); // expected-warning{{local variable 'local2' does not live long enough}}
- } // expected-note 2 {{destroyed here}}
+ } // expected-note {{local variable 'local1' is destroyed here}} expected-note {{local variable 'local2' is destroyed here}}
(void)v; // expected-note 2 {{later used here}}
}
More information about the cfe-commits
mailing list