================
@@ -454,6 +462,17 @@ void FactsGenerator::handleLifetimeEnds(const
CFGLifetimeEnds &LifetimeEnds) {
BL->getID(), LifetimeEnds.getTriggerStmt()->getEndLoc()));
}
}
+ // In loops, the back-edge can make a dead origin appear live at its
+ // pointee's ExpireFact. Expiring the origin here prevents that.
+ if (OriginList *List = getOriginsList(*LifetimeEndsVD)) {
+ for (OriginList *L = List; L; L = L->peelOuterOrigin()) {
----------------
aeft wrote:
For the test case:
```cpp
void multi_level_pointer_in_loop_2() {
MyObj obj;
MyObj* p;
for (int i = 0; i < 10; ++i) {
MyObj** pp;
pp = &p;
(void)**pp;
}
(void)*p;
}
```
Debug output:
```
Block B3:
...
Expire (2 (Path: pp))
Expire (3 (Path: pp))
ExpireOrigin (6 (Decl: pp, Type : MyObj **))
ExpireOrigin (7 (Decl: pp, Type : MyObj *))
Block ...:
...
Block B1:
...
Expire (1 (Path: p))
Expire (5 (Path: p))
ExpireOrigin (2 (Decl: p, Type : MyObj *))
```
Even though we go through the list, we don't emit expire facts for `p`'s
origins, the list only contains origins private to `pp`. Origin 7 `(Decl: pp,
Type: MyObj *)` is pp's own inner tracking slot, distinct from origin 2 `(Decl:
p, Type: MyObj *)`. The dataflow copies loans from p's origin into pp's inner
origin via `OriginFlowFact`, but they remain separate origin IDs. Expiring 7
does not affect 2.
That said, I may be missing the semantic issue you're pointing out. Could you
elaborate on what "does not reflect the language semantics" means here? Is
there a concrete scenario where expiring pp's inner origins would produce a
wrong result?
https://github.com/llvm/llvm-project/pull/182368
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits