https://github.com/usx95 updated 
https://github.com/llvm/llvm-project/pull/203577

>From 961f92d6392188517ef9b4d5360897bad44f899b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <[email protected]>
Date: Fri, 12 Jun 2026 16:25:09 +0000
Subject: [PATCH] users/usx95/helpful-invalidations

---
 .../clang/Basic/DiagnosticSemaKinds.td        |   8 +-
 clang/lib/Sema/SemaLifetimeSafety.h           |  20 ++-
 .../Sema/LifetimeSafety/invalidations.cpp     | 148 +++++++++---------
 clang/test/Sema/LifetimeSafety/safety.cpp     |   8 +-
 4 files changed, 96 insertions(+), 88 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9691963d4fe7e..8097800e6744a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10981,7 +10981,7 @@ def warn_lifetime_safety_use_after_scope_moved : 
Warning<
    InGroup<LifetimeSafetyUseAfterScopeMoved>, DefaultIgnore;
 
 def warn_lifetime_safety_use_after_free : Warning<
-    "%select{allocated object|parameter}0 does not live long enough">,
+    "%0 does not live long enough">,
     InGroup<LifetimeSafetyUseAfterFree>, DefaultIgnore;
 
 def warn_lifetime_safety_return_stack_addr : Warning<
@@ -10995,15 +10995,15 @@ def warn_lifetime_safety_return_stack_addr_moved : 
Warning<
   InGroup<LifetimeSafetyReturnStackAddrMoved>, DefaultIgnore;
 
 def warn_lifetime_safety_invalidation
-    : Warning<"%select{object whose reference is captured|parameter}0 is later 
invalidated">,
+    : Warning<"%0 is later invalidated">,
       InGroup<LifetimeSafetyInvalidation>,
       DefaultIgnore;
 def warn_lifetime_safety_invalidated_field
-    : Warning<"%select{object whose reference|parameter which}0 escapes to a 
field is later invalidated">,
+    : Warning<"%0 escapes to the %1 and is later invalidated">,
       InGroup<LifetimeSafetyInvalidation>,
       DefaultIgnore;
 def warn_lifetime_safety_invalidated_global
-    : Warning<"%select{object whose reference|parameter which}0 escapes to 
global or static storage is later invalidated">,
+    : Warning<"%0 escapes to the %1 and is later invalidated">,
       InGroup<LifetimeSafetyInvalidation>,
       DefaultIgnore;
 
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h 
b/clang/lib/Sema/SemaLifetimeSafety.h
index 565c30f74cf9a..36ad0a8a358ae 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -151,7 +151,7 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
                        ? diag::note_lifetime_safety_freed_here
                        : diag::note_lifetime_safety_invalidated_here;
     S.Diag(IssueExpr->getExprLoc(), WarnDiag)
-        << false << IssueExpr->getSourceRange();
+        << getDiagSubjectDescription(IssueExpr) << IssueExpr->getSourceRange();
     S.Diag(InvalidationExpr->getExprLoc(), UseDiag)
         << InvalidationExpr->getSourceRange();
     S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)
@@ -168,7 +168,7 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
                        : diag::note_lifetime_safety_invalidated_here;
 
     S.Diag(PVD->getSourceRange().getBegin(), WarnDiag)
-        << true << PVD->getSourceRange();
+        << getDiagSubjectDescription(PVD) << PVD->getSourceRange();
     S.Diag(InvalidationExpr->getExprLoc(), UseDiag)
         << InvalidationExpr->getSourceRange();
     S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)
@@ -183,7 +183,9 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
                                 : diag::note_lifetime_safety_invalidated_here;
     S.Diag(IssueExpr->getExprLoc(),
            diag::warn_lifetime_safety_invalidated_field)
-        << false << IssueExpr->getSourceRange();
+        << getDiagSubjectDescription(IssueExpr)
+        << getDiagSubjectDescription(DanglingField)
+        << IssueExpr->getSourceRange();
     S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
         << InvalidationExpr->getSourceRange();
     S.Diag(DanglingField->getLocation(),
@@ -199,7 +201,8 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
                                 : diag::note_lifetime_safety_invalidated_here;
     S.Diag(PVD->getSourceRange().getBegin(),
            diag::warn_lifetime_safety_invalidated_field)
-        << true << PVD->getSourceRange();
+        << getDiagSubjectDescription(PVD)
+        << getDiagSubjectDescription(DanglingField) << PVD->getSourceRange();
     S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
         << InvalidationExpr->getSourceRange();
     S.Diag(DanglingField->getLocation(),
@@ -215,7 +218,9 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
                                 : diag::note_lifetime_safety_invalidated_here;
     S.Diag(IssueExpr->getExprLoc(),
            diag::warn_lifetime_safety_invalidated_global)
-        << false << IssueExpr->getSourceRange();
+        << getDiagSubjectDescription(IssueExpr)
+        << getDiagSubjectDescription(DanglingGlobal)
+        << IssueExpr->getSourceRange();
     S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
         << InvalidationExpr->getSourceRange();
     if (DanglingGlobal->isStaticLocal() || 
DanglingGlobal->isStaticDataMember())
@@ -236,7 +241,8 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
                                 : diag::note_lifetime_safety_invalidated_here;
     S.Diag(PVD->getSourceRange().getBegin(),
            diag::warn_lifetime_safety_invalidated_global)
-        << true << PVD->getSourceRange();
+        << getDiagSubjectDescription(PVD)
+        << getDiagSubjectDescription(DanglingGlobal) << PVD->getSourceRange();
     S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
         << InvalidationExpr->getSourceRange();
     if (DanglingGlobal->isStaticLocal() || 
DanglingGlobal->isStaticDataMember())
@@ -487,6 +493,8 @@ class LifetimeSafetySemaHelperImpl : public 
LifetimeSafetySemaHelper {
     E = E->IgnoreImpCasts();
     if (isa<MaterializeTemporaryExpr>(E))
       return "temporary object";
+    if (isa<CXXNewExpr>(E))
+      return "allocated object";
 
     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
       return getDiagSubjectDescription(DRE->getDecl());
diff --git a/clang/test/Sema/LifetimeSafety/invalidations.cpp 
b/clang/test/Sema/LifetimeSafety/invalidations.cpp
index 35077b547fc95..301822f066de8 100644
--- a/clang/test/Sema/LifetimeSafety/invalidations.cpp
+++ b/clang/test/Sema/LifetimeSafety/invalidations.cpp
@@ -7,7 +7,7 @@ bool Bool();
 namespace SimpleResize {
 void IteratorInvalidAfterResize(int new_size) {
   std::vector<int> v;
-  auto it = std::begin(v);  // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = std::begin(v);  // expected-warning {{local variable 'v' is later 
invalidated}}
   v.resize(new_size);       // expected-note {{invalidated here}}
   *it;                      // expected-note {{later used here}}
 }
@@ -48,7 +48,7 @@ void PointerToContainerTest(std::vector<int>* v) {
 
 namespace InvalidateBeforeSwap {
 void InvalidateBeforeSwapIterators(std::vector<int> v1, std::vector<int> v2) {
-  auto it1 = std::begin(v1); // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it1 = std::begin(v1); // expected-warning {{parameter 'v1' is later 
invalidated}}
   auto it2 = std::begin(v2);
   if (it1 == std::end(v1) || it2 == std::end(v2)) return;
   *it1 = 0;     // ok
@@ -62,7 +62,7 @@ void InvalidateBeforeSwapIterators(std::vector<int> v1, 
std::vector<int> v2) {
 }
 
 void InvalidateBeforeSwapContainers(std::vector<int> v1, std::vector<int> v2) {
-  auto it1 = std::begin(v1);  // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it1 = std::begin(v1);  // expected-warning {{parameter 'v1' is later 
invalidated}}
   auto it2 = std::begin(v2);
   if (it1 == std::end(v1) || it2 == std::end(v2)) return;
   *it1 = 0;     // ok
@@ -77,7 +77,7 @@ bool A();
 bool B();
 void SameConditionInvalidatesThenValidatesIterator() {
   std::vector<int> container;
-  auto it = container.begin(); // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = container.begin(); // expected-warning {{local variable 
'container' is later invalidated}}
   if (it == container.end()) return;
   const bool a = A();
   if (a) {
@@ -108,7 +108,7 @@ void MergeWithDifferentContainerValuesInvalidated() {
   std::vector<int> v1, v2, v3;
   auto it = std::find(v1.begin(), v1.end(), 10);
   if (Bool()) {
-    it = std::find(v2.begin(), v2.end(), 10);  // expected-warning {{object 
whose reference is captured is later invalidated}}
+    it = std::find(v2.begin(), v2.end(), 10);  // expected-warning {{local 
variable 'v2' is later invalidated}}
   } else {
     it = std::find(v3.begin(), v3.end(), 10);
   }
@@ -119,7 +119,7 @@ void MergeWithDifferentContainerValuesInvalidated() {
 
 namespace InvalidationInLoops {
 void IteratorInvalidationInAForLoop(std::vector<int> v) {
-  for (auto it = std::begin(v);  // expected-warning {{object whose reference 
is captured is later invalidated}}
+  for (auto it = std::begin(v);  // expected-warning {{parameter 'v' is later 
invalidated}}
        it != std::end(v);
        ++it) {  // expected-note {{later used here}}
     if (Bool()) {
@@ -129,7 +129,7 @@ void IteratorInvalidationInAForLoop(std::vector<int> v) {
 }
 
 void IteratorInvalidationInAWhileLoop(std::vector<int> v) {
-  auto it = std::begin(v);  // expected-warning {{object whose reference is 
captured is later invalidated}}
+  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}}
@@ -154,7 +154,7 @@ void 
NoIteratorInvalidationInAWhileLoopErase(std::unordered_map<int, int> mp) {
 }
 
 void IteratorInvalidationInAForeachLoop(std::vector<int> v) {
-  for (int& x : v) { // expected-warning {{object whose reference is captured 
is later invalidated}} \
+  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}}
@@ -183,7 +183,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 
{{object whose reference is captured is later invalidated}}
+  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}}
   }
@@ -201,7 +201,7 @@ void UseReturnedIteratorAfterInsert(std::vector<int> v) {
 }
 
 void UseInvalidIteratorAfterInsert(std::vector<int> v) {
-  auto it = std::begin(v);  // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = std::begin(v);  // expected-warning {{parameter 'v' is later 
invalidated}}
   v.insert(it, 10);         // expected-note {{invalidated here}}
   if (it != std::end(v)) {  // expected-note {{later used here}}
     *it;
@@ -220,7 +220,7 @@ void IteratorValidAfterInsert(std::vector<int> v) {
 }
 
 void IteratorInvalidAfterInsert(std::vector<int> v, int value) {
-  auto it = std::begin(v);  // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = std::begin(v);  // expected-warning {{parameter 'v' is later 
invalidated}}
   v.insert(it, 0);          // expected-note {{invalidated here}}
   *it;                      // expected-note {{later used here}}
 }
@@ -228,7 +228,7 @@ void IteratorInvalidAfterInsert(std::vector<int> v, int 
value) {
 
 namespace SimpleInvalidIterators {
 void IteratorUsedAfterErase(std::vector<int> v) {
-  auto it = std::begin(v);          // expected-warning {{object whose 
reference is captured is later invalidated}}
+  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}}
@@ -236,7 +236,7 @@ void IteratorUsedAfterErase(std::vector<int> v) {
   }
 }
 
-void IteratorUsedAfterPushBackParam(std::vector<int>& v) { // expected-warning 
{{parameter is later invalidated}}
+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}}
@@ -245,7 +245,7 @@ void IteratorUsedAfterPushBackParam(std::vector<int>& v) { 
// expected-warning {
 }
 
 void IteratorUsedAfterPushBack(std::vector<int> v) {
-  auto it = std::begin(v); // expected-warning {{object whose reference is 
captured is later invalidated}}
+  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}}
   }
@@ -254,14 +254,14 @@ void IteratorUsedAfterPushBack(std::vector<int> v) {
 
 void IteratorUsedAfterPreIncrement() {
   std::vector<int> v;
-  auto it = v.begin();      // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = v.begin();      // expected-warning {{local variable 'v' is later 
invalidated}}
   auto next = ++it;
   v.push_back(1);           // expected-note {{invalidated here}}
   (void)*next;              // expected-note {{later used here}}
 }
 
 void IteratorUsedAfterPostDecrement(std::vector<int> v) {
-  auto it = v.rbegin();     // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = v.rbegin();     // expected-warning {{parameter 'v' is later 
invalidated}}
   auto prev = it--;
   v.push_back(1);           // expected-note {{invalidated here}}
   (void)*prev;              // expected-note {{later used here}}
@@ -269,21 +269,21 @@ void IteratorUsedAfterPostDecrement(std::vector<int> v) {
 
 void IteratorUsedAfterAddition() {
   std::vector<int> v;
-  auto it = v.cbegin();     // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = v.cbegin();     // expected-warning {{local variable 'v' is later 
invalidated}}
   auto next = it + 5;
   v.push_back(1);           // expected-note {{invalidated here}}
   (void)*next;              // expected-note {{later used here}}
 }
 
 void IteratorUsedAfterReverseSubtraction(std::vector<int> v) {
-  auto it = v.crbegin();    // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = v.crbegin();    // expected-warning {{parameter 'v' is later 
invalidated}}
   auto prev = 5 - it;
   v.push_back(1);           // expected-note {{invalidated here}}
   (void)*prev;              // expected-note {{later used here}}
 }
 
 void IteratorUsedAfterAddAdd(std::vector<int> v) {
-  auto it = v.cbegin();     // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = v.cbegin();     // expected-warning {{parameter 'v' is later 
invalidated}}
   auto next = (it + 5) + 5;
   v.push_back(1);           // expected-note {{invalidated here}}
   (void)*next;              // expected-note {{later used here}}
@@ -291,14 +291,14 @@ void IteratorUsedAfterAddAdd(std::vector<int> v) {
 
 void IteratorUsedAfterMixedAddition() {
   std::vector<int> v;
-  auto it = v.cbegin();         // expected-warning {{object whose reference 
is captured is later invalidated}}
+  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}}
   (void)*next;                  // expected-note {{later used here}}
 }
 
 void IteratorUsedAfterPreIncrementAddAssign(std::vector<int> v) {
-  auto it = v.begin();          // expected-warning {{object whose reference 
is captured is later invalidated}}
+  auto it = v.begin();          // expected-warning {{parameter 'v' is later 
invalidated}}
   it = ++it + 1 + 2;
   v.push_back(1);               // expected-note {{invalidated here}}
   (void)*it;                    // expected-note {{later used here}}
@@ -306,7 +306,7 @@ void 
IteratorUsedAfterPreIncrementAddAssign(std::vector<int> v) {
 
 void IteratorUsedAfterBeginAddAssign() {
   std::vector<int> v;
-  auto it = v.begin() + 1;      // expected-warning {{object whose reference 
is captured is later invalidated}}
+  auto it = v.begin() + 1;      // expected-warning {{local variable 'v' is 
later invalidated}}
   v.push_back(1);               // expected-note {{invalidated here}}
   (void)*it;                    // expected-note {{later used here}}
 }
@@ -314,7 +314,7 @@ void IteratorUsedAfterBeginAddAssign() {
 void IteratorUsedAfterStdBeginAddAssign() {
   std::vector<int> v;
   std::vector<int>::iterator it;
-  it = std::begin(v) + 1;       // expected-warning {{object whose reference 
is captured is later invalidated}}
+  it = std::begin(v) + 1;       // expected-warning {{local variable 'v' is 
later invalidated}}
   v.push_back(1);               // expected-note {{invalidated here}}
   (void)*it;                    // expected-note {{later used here}}
 }
@@ -324,12 +324,12 @@ namespace InvalidatingThroughContainerAliases {
 void IteratorInvalidatedThroughLocalReferenceAlias() {
   std::vector<int> vv;
   std::vector<int> &v = vv;
-  auto it = vv.begin(); // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = vv.begin(); // expected-warning {{local variable 'vv' is later 
invalidated}}
   v.push_back(42);      // expected-note {{invalidated here}}
   (void)it;             // expected-note {{later used here}}
 }
 
-void IteratorInvalidatedThroughPointerParameter(std::vector<int> *v) { // 
expected-warning {{parameter is later invalidated}}
+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}}
   (void)it;         // expected-note {{later used here}}
@@ -347,7 +347,7 @@ void ParenthesizedContainerInvalidatesIterator() {
 
 namespace ContainerObjectAliases {
 // FIXME: Distinguish owner-borrow from content-borrow.
-void PointerParameterObjectUseIsOk(std::vector<int> *v) { // expected-warning 
{{parameter is later invalidated}}
+void PointerParameterObjectUseIsOk(std::vector<int> *v) { // expected-warning 
{{parameter 'v' is later invalidated}}
   v->push_back(42); // expected-note {{invalidated here}}
   (void)v;          // expected-note {{later used here}}
 }
@@ -355,7 +355,7 @@ void PointerParameterObjectUseIsOk(std::vector<int> *v) { 
// expected-warning {{
 // FIXME: Distinguish owner-borrow from content-borrow.
 void LocalPointerAliasObjectUseIsOk() {
   std::vector<int> vv;
-  std::vector<int> *v = &vv; // expected-warning {{object whose reference is 
captured is later invalidated}}
+  std::vector<int> *v = &vv; // expected-warning {{local variable 'vv' is 
later invalidated}}
   v->push_back(42);          // expected-note {{invalidated here}}
   (void)*v;                  // expected-note {{later used here}}
 }
@@ -363,7 +363,7 @@ void LocalPointerAliasObjectUseIsOk() {
 // FIXME: Distinguish owner-borrow from content-borrow.
 void LocalReferenceAliasObjectUseIsOk() {
   std::vector<int> vv;
-  std::vector<int> &v = vv; // expected-warning {{object whose reference is 
captured is later invalidated}}
+  std::vector<int> &v = vv; // expected-warning {{local variable 'vv' is later 
invalidated}}
   v.push_back(42);          // expected-note {{invalidated here}}
   (void)v;                  // expected-note {{later used here}}
 }
@@ -374,7 +374,7 @@ namespace ElementReferences {
 
 void ReferenceToVectorElement() {
   std::vector<int> v = {1, 2, 3};
-  int& ref = v[0]; // expected-warning {{object whose reference is captured is 
later invalidated}}
+  int& ref = v[0]; // expected-warning {{local variable 'v' is later 
invalidated}}
   v.push_back(4);  // expected-note {{invalidated here}}
   ref = 10;        // expected-note {{later used here}}
   (void)ref;
@@ -382,14 +382,14 @@ void ReferenceToVectorElement() {
 
 void PointerRefToVectorElement() {
   std::vector<int*> v = {nullptr, nullptr};
-  int*& ref = v[0];     // expected-warning {{object whose reference is 
captured is later invalidated}}
+  int*& ref = v[0];     // expected-warning {{local variable 'v' is later 
invalidated}}
   v.push_back(nullptr); // expected-note {{invalidated here}}
   ref = nullptr;        // expected-note {{later used here}}
 }
 
 void PointerToVectorElement() {
   std::vector<int> v = {1, 2, 3};
-  int* ptr = &v[0];  // expected-warning {{object whose reference is captured 
is later invalidated}}
+  int* ptr = &v[0];  // expected-warning {{local variable 'v' is later 
invalidated}}
   v.resize(100);     // expected-note {{invalidated here}}
   *ptr = 10;         // expected-note {{later used here}}
 }
@@ -405,13 +405,13 @@ void SelfInvalidatingMap() {
   mp[1] = "42";
   mp[2]     // expected-note {{invalidated here}}
     =
-    mp[1];  // expected-warning {{object whose reference is captured is later 
invalidated}} expected-note {{later used here}}
+    mp[1];  // expected-warning {{local variable 'mp' is later invalidated}} 
expected-note {{later used here}}
 }
 
 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 {{object whose reference is 
captured is later invalidated}}
+  auto it = mp.find(3); // expected-warning {{local variable 'mp' is later 
invalidated}}
   mp.erase(mp.find(4)); // expected-note {{invalidated here}}
   if (it != mp.end())   // expected-note {{later used here}}
     *it;
@@ -421,12 +421,12 @@ void InvalidateErase() {
 namespace Strings {
 
 void append(std::string str) {
-  std::string_view view = str;  // expected-warning {{object whose reference 
is captured is later invalidated}}
+  std::string_view view = str;  // expected-warning {{parameter 'str' is later 
invalidated}}
   str += "456";                 // expected-note {{invalidated here}}
   (void)view;                   // expected-note {{later used here}}
 }
 void reassign(std::string str, std::string str2) {
-  std::string_view view = str;  // expected-warning {{object whose reference 
is captured is later invalidated}}
+  std::string_view view = str;  // expected-warning {{parameter 'str' is later 
invalidated}}
   str = str2;                   // expected-note {{invalidated here}}
   (void)view;                   // expected-note {{later used here}}
 }
@@ -434,7 +434,7 @@ void reassign(std::string str, std::string str2) {
 
 // FIXME: This should be diagnosed as use-after-invalidation but with 
potential move.
 void ReassigningAfterMove(std::string str, std::string str2) {
-  std::string_view view = str;  // expected-warning {{object whose reference 
is captured is later invalidated}}
+  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}}
@@ -478,7 +478,7 @@ void ConditionalFieldInvalidatesIterator(bool flag) {
 // FIXME: Requires field-sensitive AccessPaths to fix.
 void Invalidate1Use2ViaRefIsOk() {
     S s;
-    auto it = s.strings2.begin(); // expected-warning {{object whose reference 
is captured is later invalidated}}
+    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}}
     *it;                          // expected-note {{later used here}}
@@ -492,13 +492,13 @@ void Invalidate1UseSIsOk() {
 // FIXME: Distinguish owner-borrow from content-borrow.
 void PointerToContainerIsOk() {
   std::vector<std::string> s;
-  std::vector<std::string>* p = &s; // expected-warning {{object whose 
reference is captured is later invalidated}}
+  std::vector<std::string>* p = &s; // expected-warning {{local variable 's' 
is later invalidated}}
   p->push_back("1");                // expected-note {{invalidated here}}
   (void)*p;                         // expected-note {{later used here}}
 }
 void IteratorFromPointerToContainerIsInvalidated() {
   std::vector<std::string> s;
-  std::vector<std::string>* p = &s; // expected-warning {{object whose 
reference is captured is later invalidated}}
+  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}}
   *it;                              // expected-note {{later used here}}
@@ -507,7 +507,7 @@ void IteratorFromPointerToContainerIsInvalidated() {
 // iterators into the outer container.
 void ChangingRegionOwnedByContainerIsOk() {
   std::vector<std::string> subdirs;
-  for (std::string& path : subdirs) // expected-warning {{object whose 
reference is captured is later invalidated}} expected-note {{later used here}}
+  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}}
 }
 
@@ -520,7 +520,7 @@ std::string StableString;
 struct SinkOwnerBorrow {
   std::string *dest_; // expected-note {{this field dangles}}
 
-  SinkOwnerBorrow(std::string *dest, int n) : dest_(dest) { // 
expected-warning {{parameter which escapes to a field is later invalidated}}
+  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}}
   }
@@ -529,7 +529,7 @@ struct SinkOwnerBorrow {
 struct SinkInteriorBorrow {
   const char *dest_; // expected-note {{this field dangles}}
 
-  SinkInteriorBorrow(std::string *dest, int n) : dest_(dest->data()) { // 
expected-warning {{parameter which escapes to a field is later invalidated}}
+  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}}
   }
@@ -547,38 +547,38 @@ struct S {
 
   void InvalidatedFieldLocalVector() {
     std::vector<std::string> strings;
-    FieldFromLocalVector = *strings.begin(); // expected-warning {{object 
whose reference escapes to a field is later invalidated}}
+    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}}
   }
 
   void InvalidatedFieldByValueParamVector(std::vector<std::string> strings) {
-    FieldFromByValueParamVector = *strings.begin(); // expected-warning 
{{object whose reference escapes to a field is later invalidated}}
+    FieldFromByValueParamVector = *strings.begin(); // expected-warning 
{{parameter 'strings' escapes to the field 'FieldFromByValueParamVector' and is 
later invalidated}}
     strings.push_back("1"); // expected-note {{invalidated here}}
   }
 
   void InvalidatedFieldLocalString() {
     std::string s;
-    FieldFromLocalString = s; // expected-warning {{object whose reference 
escapes to a field is later invalidated}}
+    FieldFromLocalString = s; // expected-warning {{local variable 's' escapes 
to the field 'FieldFromLocalString' and is later invalidated}}
     s.clear(); // expected-note {{invalidated here}}
   }
 
   void InvalidatedFieldByValueParamString(std::string s) {
-    FieldFromByValueParamString = s; // expected-warning {{object whose 
reference escapes to a field is later invalidated}}
+    FieldFromByValueParamString = s; // expected-warning {{parameter 's' 
escapes to the field 'FieldFromByValueParamString' and is later invalidated}}
     s.clear(); // expected-note {{invalidated here}}
   }
 
-  void InvalidatedFieldRefParamString(std::string &s) { // expected-warning 
{{parameter which escapes to a field is later invalidated}}
+  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}}
   }
 
   void InvalidatedFieldDelete() {
-    int *p = new int; // expected-warning {{object whose reference escapes to 
a field is later invalidated}}
+    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}}
   }
 
-  void InvalidatedFieldDeleteParam(int *p) { // expected-warning {{parameter 
which escapes to a field is later invalidated}}
+  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}}
   }
@@ -607,27 +607,27 @@ struct S {
 
 void InvalidatedGlobalLocalVector() {
   std::vector<std::string> strings;
-  GlobalFromLocalVector = *strings.begin(); // expected-warning {{object whose 
reference escapes to global or static storage is later invalidated}}
+  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}}
 }
 
 void InvalidatedGlobalByValueParamString(std::string s) {
-  GlobalFromByValueParamString = s; // expected-warning {{object whose 
reference escapes to global or static storage is later invalidated}}
+  GlobalFromByValueParamString = s; // expected-warning {{parameter 's' 
escapes to the global variable 'GlobalFromByValueParamString' and is later 
invalidated}}
   s.clear(); // expected-note {{invalidated here}}
 }
 
-void InvalidatedGlobalRefParamString(std::string &s) { // expected-warning 
{{parameter which escapes to global or static storage is later invalidated}}
+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}}
 }
 
 void InvalidatedGlobalDelete() {
-  int *p = new int; // expected-warning {{object whose reference escapes to 
global or static storage is later invalidated}}
+  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}}
 }
 
-void InvalidatedGlobalDeleteParam(int *p) { // expected-warning {{parameter 
which escapes to global or static storage is later invalidated}}
+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}}
 }
@@ -635,13 +635,13 @@ void InvalidatedGlobalDeleteParam(int *p) { // 
expected-warning {{parameter whic
 void InvalidatedStaticLocalString() {
   static std::string_view StaticFromLocalString; // expected-note {{this 
static storage dangles}}
   std::string s;
-  StaticFromLocalString = s; // expected-warning {{object whose reference 
escapes to global or static storage is later invalidated}}
+  StaticFromLocalString = s; // expected-warning {{local variable 's' escapes 
to the static variable 'StaticFromLocalString' and is later invalidated}}
   s.clear(); // expected-note {{invalidated here}}
 }
 
 void InvalidatedStaticMemberString() {
   std::string s;
-  S::StaticMember = s; // expected-warning {{object whose reference escapes to 
global or static storage is later invalidated}}
+  S::StaticMember = s; // expected-warning {{local variable 's' escapes to the 
static variable 'StaticMember' and is later invalidated}}
   s.clear(); // expected-note {{invalidated here}}
 }
 
@@ -714,14 +714,14 @@ void SetExtractDoesNotInvalidateOthers() {
 
 void SetClearInvalidates() {
   std::set<int> s;
-  auto it = s.begin(); // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = s.begin(); // expected-warning {{local variable 's' is later 
invalidated}}
   s.clear(); // expected-note {{invalidated here}}
   *it; // expected-note {{later used here}}
 }
 
 void MapClearInvalidates() {
   std::map<int, int> m;
-  auto it = m.begin();  // expected-warning {{object whose reference is 
captured is later invalidated}}
+  auto it = m.begin();  // expected-warning {{local variable 'm' is later 
invalidated}}
   m.clear(); // expected-note {{invalidated here}}
   *it; // expected-note {{later used here}}
 }
@@ -740,7 +740,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 {{object whose reference is 
captured is later invalidated}} \
+    PrintMax(mp[a], mp[b]); // expected-warning {{parameter 'mp' is later 
invalidated}} \
                                  // expected-note {{invalidated here}} \
                                  // expected-note {{later used here}}
 }
@@ -750,7 +750,7 @@ void 
FlatMapSubscriptMultipleCallsInvalidate(std::flat_map<int, int> mp, int a,
 namespace lambda_capture_invalidation {
 void captured_view_invalidated_by_owner() {
   std::string s = "42";
-  std::string_view p = s; // expected-warning {{object whose reference is 
captured is later invalidated}}
+  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}}
   lambda();  // expected-note {{later used here}}
@@ -758,7 +758,7 @@ void captured_view_invalidated_by_owner() {
 
 void multiple_captures_one_invalidated() {
   std::string s1 = "a", s2 = "b";
-  std::string_view p1 = s1, p2 = s2; // expected-warning {{object whose 
reference is captured is later invalidated}}
+  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}}
   lambda();  // expected-note {{later used here}}
@@ -793,7 +793,7 @@ struct S {
   void bar();
   void baz(){
     std::vector<std::string> vec = {"42"};
-    v = vec[0];         // expected-warning {{object whose reference is 
captured is later invalidated}}
+    v = vec[0];         // expected-warning {{local variable 'vec' is later 
invalidated}}
     vec.push_back("1"); // expected-note {{invalidated here}}
     bar();              // expected-note {{later used here}}
     v = nullptr;
@@ -806,7 +806,7 @@ namespace callable_wrappers {
 void function_captured_ref_invalidated() {
   std::vector<int> v;
   v.push_back(1);
-  std::function<void()> f = [&r = v[0]]() { (void)r; }; // expected-warning 
{{object whose reference is captured is later invalidated}}
+  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}}
   (void)f; // expected-note {{later used here}}
 }
@@ -818,14 +818,14 @@ namespace explicit_destructor {
 
 void explicit_destructor_invalidates_pointer() {
   std::string s = "42";
-  const char *p = s.data(); // expected-warning {{object whose reference is 
captured is later invalidated}}
+  const char *p = s.data(); // expected-warning {{local variable 's' is later 
invalidated}}
   s.~basic_string();        // expected-note {{invalidated here}}
   (void)*p;                 // expected-note {{later used here}}
 }
 
 void pointer_destructor_invalidates_pointer() {
   char storage[sizeof(std::string)];
-  std::string *obj = new (storage) std::string("42"); // expected-warning 
{{object whose reference is captured is later invalidated}}
+  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}}
   (void)*p;                                           // expected-note {{later 
used here}}
@@ -833,7 +833,7 @@ void pointer_destructor_invalidates_pointer() {
 
 void destroy_at_invalidates_pointer() {
   char storage[sizeof(std::string)];
-  std::string *obj = new (storage) std::string("42"); // expected-warning 
{{object whose reference is captured is later invalidated}}
+  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}}
   (void)*p;                                           // expected-note {{later 
used here}}
@@ -852,21 +852,21 @@ void destroy_at_then_placement_new_rescues_pointer() {
 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 {{object whose reference 
is captured is later invalidated}}
+  const char *p = arr[0].data(); // expected-warning {{local variable 'arr' is 
later invalidated}}
   std::destroy_at(&arr_ref);     // expected-note {{invalidated here}}
   (void)*p;                      // expected-note {{later used here}}
 }
 
 void reference_destructor_invalidates_pointer() {
   std::string s = "42";
-  std::string &ref = s;       // expected-warning {{object whose reference is 
captured is later invalidated}}
+  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}}
   (void)*p;                   // expected-note {{later used here}}
 }
 
 void destroy_at_ternary_operator(bool flag) {
-  std::string* str1 = new std::string; // expected-warning {{object whose 
reference is captured is later invalidated}}
+  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}}
@@ -880,7 +880,7 @@ struct StringOwner {
 // FIXME: False-positive
 void member_destructor_invalidates_pointer() {
   StringOwner owner = {"42", "43"};
-  const char *p = owner.s.data(); // expected-warning {{object whose reference 
is captured is later invalidated}}
+  const char *p = owner.s.data(); // expected-warning {{local variable 'owner' 
is later invalidated}}
   owner.t.~basic_string();        // expected-note {{invalidated here}}
   (void)*p;                       // expected-note {{later used here}}
 }
@@ -891,7 +891,7 @@ namespace unique_ptr_invalidation {
 
 void invalid_after_reset() {
   std::unique_ptr<int> up(new int);
-  int *p = up.get(); // expected-warning {{object whose reference is captured 
is later invalidated}}
+  int *p = up.get(); // expected-warning {{local variable 'up' is later 
invalidated}}
   up.reset();        // expected-note {{invalidated here}}
   (void)*p;          // expected-note {{later used here}}
 }
@@ -899,14 +899,14 @@ void invalid_after_reset() {
 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 {{object whose reference is 
captured is later invalidated}}
+  int *p = up.get();     // expected-warning {{local variable 'up' is later 
invalidated}}
   up = std::move(other); // expected-note {{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 {{object whose reference is captured 
is later invalidated}}
+  int *p = up.get(); // expected-warning {{local variable 'up' is later 
invalidated}}
   up = nullptr;      // expected-note {{invalidated here}}
   (void)*p;          // expected-note {{later used here}}
 }
@@ -914,7 +914,7 @@ void invalid_after_null_assign() {
 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 {{object whose 
reference is captured is later invalidated}}
+  int *p = flag ? up.get() : other.get(); // expected-warning {{local variable 
'up' is later invalidated}}
   up.reset();                             // expected-note {{invalidated 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 d976baa545b8c..1c4b3c117fb00 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -2943,7 +2943,7 @@ void delete_pointer_propagation_use_after_free() {
   (void)(*pp)->id;      // expected-note {{later used here}}
 }
 
-void delete_param_pointer(int* x) { // expected-warning {{parameter does not 
live long enough}}
+void delete_param_pointer(int* x) { // expected-warning {{parameter 'x' does 
not live long enough}}
   delete x;                         // expected-note {{freed here}}
   (void)x;                          // expected-note {{later used here}}
 }
@@ -2957,7 +2957,7 @@ struct S {
   }
 };
 
-void use_inner_origin_after_delete(MyObj* obj) { // expected-warning 
{{parameter does not live long enough}}
+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}}
     (void)*p;                                     // expected-note {{later 
used here}}
@@ -3009,14 +3009,14 @@ void delete_through_pointer_field() {
 
 void delete_stack_object() {
   MyObj obj;
-  MyObj* p = &obj; // expected-warning {{allocated object does not live long 
enough}}
+  MyObj* p = &obj; // expected-warning {{local variable 'obj' does not live 
long enough}}
   delete &obj;     // expected-note {{freed here}}
   (void)p->id;     // expected-note {{later used here}}
 }
 
 void delete_stack_object_int() {
   int obj;
-  int* p = &obj;  // expected-warning {{allocated object does not live long 
enough}}
+  int* p = &obj;  // expected-warning {{local variable 'obj' does not live 
long enough}}
   delete &obj;    // expected-note {{freed here}}
   (void)*p;       // expected-note {{later used here}}
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to