[PATCH] D30489: [analyzer] catch out of bounds for VLA
Daniel Marjamäki via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 1 01:37:54 PST 2017
danielmarjamaki created this revision.
This is a work in progress patch. I try to detect such error:
void foo(int X) {
int Buf[X];
Buf[X] = 0;
}
The patch successfully detects this bug. However it writes FP when you try to take the address.
I would like to know if you think my approach to add a checkPreStmt is good. I would need to add logic to handle *(Buf+X) also.
This checker doesn't really logically belong in the ArrayBounds checker but from a user perspective it seems to belong there. I can move it to a new checker if that sounds best.
Repository:
rL LLVM
https://reviews.llvm.org/D30489
Files:
lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
Index: lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
+++ lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
@@ -24,17 +24,20 @@
namespace {
class ArrayBoundChecker :
- public Checker<check::Location> {
+ public Checker<check::Location, check::PreStmt<ArraySubscriptExpr>> {
mutable std::unique_ptr<BuiltinBug> BT;
+ mutable std::unique_ptr<BuiltinBug> BT_VLA;
public:
void checkLocation(SVal l, bool isLoad, const Stmt* S,
CheckerContext &C) const;
+ void checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const;
};
}
void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
CheckerContext &C) const {
+
// Check for out of bound array element access.
const MemRegion *R = l.getAsRegion();
if (!R)
@@ -88,6 +91,39 @@
C.addTransition(StInBound);
}
+void ArrayBoundChecker::checkPreStmt(const ArraySubscriptExpr *A, CheckerContext &C) const
+{
+ const Expr *Base = A->getBase()->IgnoreImpCasts();
+
+ ASTContext &Ctx = C.getASTContext();
+ const VariableArrayType *VLA = Ctx.getAsVariableArrayType(Base->getType());
+ if (!VLA)
+ return;
+
+ ProgramStateRef State = C.getState();
+ SVal sizeV = State->getSVal(VLA->getSizeExpr(), C.getLocationContext());
+ SVal idxV = State->getSVal(A->getIdx(), C.getLocationContext());
+
+ // Is idx greater than size?
+ SValBuilder &Bldr = C.getSValBuilder();
+ SVal GE = Bldr.evalBinOp(State, BO_GE, idxV, sizeV, Bldr.getConditionType());
+ if (!GE.isConstant(1))
+ return;
+
+ ExplodedNode *N = C.generateErrorNode(State);
+ if (!N)
+ return;
+
+ if (!BT_VLA)
+ BT_VLA.reset(new BuiltinBug(
+ this, "Out-of-bound VLA access",
+ "Out-of-bounds VLA access (symbolically this index is greater than the size)"));
+ // Generate a report for this bug.
+ auto report = llvm::make_unique<BugReport>(*BT_VLA, BT_VLA->getDescription(), N);
+ report->addRange(A->getSourceRange());
+ C.emitReport(std::move(report));
+}
+
void ento::registerArrayBoundChecker(CheckerManager &mgr) {
mgr.registerChecker<ArrayBoundChecker>();
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30489.90128.patch
Type: text/x-patch
Size: 2256 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170301/c0aa93ba/attachment-0001.bin>
More information about the cfe-commits
mailing list