[clang] [LifetimeSafety] Extend function handling invalidating calls (PR #195064)
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 30 07:07:45 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));
----------------
usx95 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
Yeah. My point is that you do not have to get a `DeclRefExpr`. Special casing only for it misses out on other LValue'd expressions.
Example:
```cpp
std::string* str1 = new std::string(1);
std::string* str2 = new std::string(2);
const char *p = str1->data();
std::destroy_at(flag ? str1 : str2);
(void)*p;
```
https://github.com/llvm/llvm-project/pull/195064
More information about the cfe-commits
mailing list