[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