================
@@ -556,8 +554,47 @@ class FactGeneratorVisitor : public
ConstStmtVisitor<FactGeneratorVisitor> {
return false;
}
+ void handleAssignment(const Expr *LHSExpr, const Expr *RHSExpr) {
+ // Find the underlying variable declaration for the left-hand side.
+ if (const auto *DRE_LHS =
+ dyn_cast<DeclRefExpr>(LHSExpr->IgnoreParenImpCasts())) {
+ markUseAsWrite(DRE_LHS);
+ if (const auto *VD_LHS = dyn_cast<ValueDecl>(DRE_LHS->getDecl()))
+ if (hasOrigin(VD_LHS->getType()))
+ // We are interested in assignments like `ptr1 = ptr2` or `ptr =
&var`
+ // LHS must be a pointer/reference type that can be an origin.
+ // RHS must also represent an origin (either another pointer/ref or
an
+ // address-of).
+ addAssignOriginFact(*VD_LHS, *RHSExpr);
+ }
+ }
+
+ // A DeclRefExpr is a use of the referenced decl. It is checked for
+ // use-after-free unless it is being written to (e.g. on the left-hand side
+ // of an assignment).
+ void handleUse(const DeclRefExpr *DRE) {
+ const auto *VD = dyn_cast<ValueDecl>(DRE->getDecl());
+ if (VD && hasOrigin(VD->getType())) {
+ UseFact *UF = FactMgr.createFact<UseFact>(DRE);
+ CurrentBlockFacts.push_back(UF);
+ assert(!UseFacts.contains(DRE));
+ UseFacts[DRE] = UF;
+ }
+ }
+
+ void markUseAsWrite(const DeclRefExpr *DRE) {
+ assert(UseFacts.contains(DRE));
+ UseFacts[DRE]->markAsWritten();
+ }
+
FactManager &FactMgr;
llvm::SmallVector<Fact *> CurrentBlockFacts;
+ // To distinguish between reads and writes for use-after-free checks, this
map
+ // stores the `UseFact` for each `DeclRefExpr`. We initially identify all
+ // `DeclRefExpr`s as "read" uses. When an assignment is processed, the use
+ // corresponding to the left-hand side is updated to be a "write", thereby
+ // exempting it from the check.
+ llvm::DenseMap<const DeclRefExpr *, UseFact *> UseFacts;
----------------
usx95 wrote:
Currently this will not be treated as write but as reads. In principle, DRE for
both `a` and `b` can be marked as write by re-traversing the LHS. I would not
go down that path just yet, and we can deal with it if need be. The chances of
false positives due to such writes (mistreated as reads) seems low.
That said, we would need to handle conditional operator in general and current
analysis does not do a great job.
https://github.com/llvm/llvm-project/pull/154316
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits