[clang] [analyzer]:fix valistChecker false negative in windows platform (PR #72951)

via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 20 20:14:17 PST 2023


https://github.com/mzyKi created https://github.com/llvm/llvm-project/pull/72951

fixed #72618  inlined_uses_arg call_vprintf_bad, but still fail in call_vsprintf_bad in valist-uninitialized-no-undef.c

>From a3bf0f3ac007ee9475fb302ea9c458814e06e6c0 Mon Sep 17 00:00:00 2001
From: miaozhiyuan <miaozhiyuan at feysh.com>
Date: Tue, 21 Nov 2023 12:07:35 +0800
Subject: [PATCH] [analyzer]:fix valistChecker false negative in windows
 platform

---
 .../StaticAnalyzer/Checkers/ValistChecker.cpp | 36 +++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
index 2d1b873abf73f09..0ac7b092aa86278 100644
--- a/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -27,8 +27,9 @@ REGISTER_SET_WITH_PROGRAMSTATE(InitializedVALists, const MemRegion *)
 namespace {
 typedef SmallVector<const MemRegion *, 2> RegionVector;
 
-class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
-                                     check::DeadSymbols> {
+class ValistChecker
+    : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
+                     check::PreStmt<DeclStmt>, check::DeadSymbols> {
   mutable std::unique_ptr<BugType> BT_leakedvalist, BT_uninitaccess;
 
   struct VAListAccepter {
@@ -49,11 +50,13 @@ class ValistChecker : public Checker<check::PreCall, check::PreStmt<VAArgExpr>,
   bool ChecksEnabled[CK_NumCheckKinds] = {false};
   CheckerNameRef CheckNames[CK_NumCheckKinds];
 
+  void checkPreStmt(const DeclStmt *DS, CheckerContext &C) const;
   void checkPreStmt(const VAArgExpr *VAA, CheckerContext &C) const;
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
 
 private:
+  bool isWinValistType(const VarDecl *VD) const;
   const MemRegion *getVAListAsRegion(SVal SV, const Expr *VAExpr,
                                      bool &IsSymbolic, CheckerContext &C) const;
   const ExplodedNode *getStartCallSite(const ExplodedNode *N,
@@ -160,6 +163,35 @@ void ValistChecker::checkPreCall(const CallEvent &Call,
   }
 }
 
+bool ValistChecker::isWinValistType(const VarDecl *VD) const {
+  ASTContext &Ctx = VD->getASTContext();
+  QualType T = VD->getType();
+  if (T.isNull()) {
+    return false;
+  }
+  return T.getDesugaredType(Ctx)->isPointerType() &&
+         T.getDesugaredType(Ctx)->getPointeeType()->isCharType();
+}
+
+void ValistChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
+  for (const auto *I : DS->decls()) {
+    if (const auto *D = dyn_cast<VarDecl>(I)) {
+      if (isWinValistType(D)) {
+        ProgramStateRef State = C.getState();
+        const LocationContext *LC = C.getLocationContext();
+        const VarRegion *R = State->getRegion(D, LC);
+        MemRegionManager &MR = R->getMemRegionManager();
+        SValBuilder &SVB = C.getSValBuilder();
+        const ElementRegion *ER =
+            MR.getElementRegion(C.getASTContext().CharTy,
+                                SVB.makeZeroArrayIndex(), R, C.getASTContext());
+        State = State->bindLoc(State->getLValue(D, LC), SVB.makeLoc(ER), LC);
+        C.addTransition(State);
+      }
+    }
+  }
+}
+
 const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,
                                                   bool &IsSymbolic,
                                                   CheckerContext &C) const {



More information about the cfe-commits mailing list