[clang] [LifetimeSafety] Detect iterator invalidation through container aliases (PR #195231)
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Fri May 1 04:47:04 PDT 2026
================
@@ -345,37 +384,41 @@ void Invalidate1Use2IsOk() {
auto it = s.strings1.begin();
s.strings2.push_back("1");
*it;
-}void Invalidate1Use2ViaRefIsOk() {
+}
+
+// FIXME: Requires field-sensitive AccessPaths to fix.
+void Invalidate1Use2ViaRefIsOk() {
S s;
- auto it = s.strings2.begin();
+ auto it = s.strings2.begin(); // expected-warning {{object whose reference is captured is later invalidated}}
auto& strings2 = s.strings2;
- strings2.push_back("1");
- *it;
+ strings2.push_back("1"); // expected-note {{invalidated here}}
+ *it; // expected-note {{later used here}}
}
void Invalidate1UseSIsOk() {
S s;
S* p = &s;
s.strings2.push_back("1");
(void)*p;
}
+// FIXME: Distinguish owner-borrow from content-borrow.
void PointerToContainerIsOk() {
std::vector<std::string> s;
- std::vector<std::string>* p = &s;
- p->push_back("1");
- (void)*p;
+ std::vector<std::string>* p = &s; // expected-warning {{object whose reference is captured is later invalidated}}
+ p->push_back("1"); // expected-note {{invalidated here}}
+ (void)*p; // expected-note {{later used here}}
}
void IteratorFromPointerToContainerIsInvalidated() {
- // FIXME: Detect this.
std::vector<std::string> s;
- std::vector<std::string>* p = &s;
+ std::vector<std::string>* p = &s; // expected-warning {{object whose reference is captured is later invalidated}}
auto it = p->begin();
- p->push_back("1");
- *it;
+ p->push_back("1"); // expected-note {{invalidated here}}
+ *it; // expected-note {{later used here}}
}
+// FIXME: `isContainerInvalidationMethod` treats `operator=` as always invalidating.
----------------
usx95 wrote:
This is indeed a prior limitation but it is not related to origins of `std::string`. The problem is the range based `for`loop here which expands to using iterators (`subdirs.begin()`) and using them to iterate the vector.
The invalidation by `operator=` is indeed correct. It would invalidate pre-existing `char*` from the string elements.
The problem is invalidating content of strings (via assignment) does not invalidate the iterator to the outer vector. And we cannot differentiate between them,
https://github.com/llvm/llvm-project/pull/195231
More information about the cfe-commits
mailing list