[clang] [LifetimeSafety] Detect iterator invalidation through container aliases (PR #195231)
Zeyi Xu via cfe-commits
cfe-commits at lists.llvm.org
Fri May 1 00:53:59 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.
----------------
zeyi2 wrote:
>From what I see this is likely an existing bug/limitation unrelated to changes in this patch, though I haven't fully verified this.
https://github.com/llvm/llvm-project/blob/8eff63f6e78c89be81e70f8600672f292d6f3731/clang/lib/Analysis/LifetimeSafety/Origins.cpp#L103-L121
It doesn't check `isGslOwnerType`, so `hasOrigins(std::string)` returns `false`. This causes the `OO_Equal` in `VisitCXXOperatorCallExpr` to be skipped.
Happy to dive deeper and send a follow-up PR to fix this if you'd like.
https://github.com/llvm/llvm-project/pull/195231
More information about the cfe-commits
mailing list