[clang] [LifetimeSafety] Extend function handling invalidating calls (PR #195064)

via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 30 06:58:41 PDT 2026


================
@@ -768,20 +768,23 @@ void FactsGenerator::handleInvalidatingCall(const Expr *Call,
                                             const FunctionDecl *FD,
                                             ArrayRef<const Expr *> Args) {
   const auto *MD = dyn_cast<CXXMethodDecl>(FD);
-  if (!MD || !MD->isInstance())
+  const bool IsInvalidatingMethod = MD && isInvalidationMethod(*MD);
+  const bool IsDestruction = isDestructionFunc(*FD);
+  if (!IsInvalidatingMethod && !IsDestruction)
     return;
 
-  if (!isInvalidationMethod(*MD))
-    return;
-  // Heuristics to turn-down false positives.
-  auto *DRE = dyn_cast<DeclRefExpr>(Args[0]);
+  // `destroy_at` get an implicit cast for the object argument, methods already
+  // give us the right shape.
+  const Expr *Target = IsDestruction ? Args[0]->IgnoreImpCasts() : Args[0];
+
+  // Heuristics to turn down false positives.
+  const auto *DRE = dyn_cast<DeclRefExpr>(Target);
   if (!DRE || DRE->getDecl()->getType()->isReferenceType())
     return;
 
-  OriginList *ThisList = getOriginsList(*Args[0]);
-  if (ThisList)
+  if (OriginList *ArgList = getOriginsList(*Args[0]))
     CurrentBlockFacts.push_back(FactMgr.createFact<InvalidateOriginFact>(
-        ThisList->getOuterOriginID(), Call));
+        ArgList->getOuterOriginID(), Call));
----------------
NeKon69 wrote:

I ignore implicit casts here for pretty much the same reason as in the previous PR - to get the actual `DeclRefExpr` instead of the `LValueToRValue` cast.

> It may make the false-negative with reference work

I can't really think of any such examples. Since destructors generally do not accept any parameters other than `this`, and `destroy_at` is a standard defined function that accepts a pointer directly, this should be fine. I may be wrong, though, here's the AST nonetheless.

```
ImplicitCastExpr 0x55559efdb638 'View *' <LValueToRValue>
`-DeclRefExpr 0x55559efdb600 'View *' lvalue Var 0x55559efd9cd0 'storage' 'View *'
```

> I would suggest to have a separate function to handleExplicitDestruction

I also thought about doing so, but in the end I didn't really see a point, because they would have pretty much identical bodies.

https://github.com/llvm/llvm-project/pull/195064


More information about the cfe-commits mailing list