================ @@ -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 llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits