diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h | 1 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp | 32 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/Checkers.td | 5 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ExperimentalChecks.cpp | 1 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/InternalChecks.h | 1 | ||||
-rw-r--r-- | test/Analysis/misc-ps-region-store.m | 4 | ||||
-rw-r--r-- | test/Analysis/outofbound.c | 2 | ||||
-rw-r--r-- | test/Analysis/rdar-6541136-region.c | 2 |
8 files changed, 26 insertions, 22 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 88b0024de6..4429c6b2a7 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -72,6 +72,7 @@ public: StmtNodeBuilder &getNodeBuilder() { return B; } ExplodedNode *&getPredecessor() { return Pred; } const GRState *getState() { return ST ? ST : B.GetState(Pred); } + const Stmt *getStmt() const { return statement; } ASTContext &getASTContext() { return Eng.getContext(); diff --git a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp index 9194791fc0..25e224e50c 100644 --- a/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp @@ -12,9 +12,11 @@ // //===----------------------------------------------------------------------===// -#include "InternalChecks.h" +#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Core/CheckerV2.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerVisitor.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" using namespace clang; @@ -22,21 +24,15 @@ using namespace ento; namespace { class ArrayBoundChecker : - public CheckerVisitor<ArrayBoundChecker> { - BuiltinBug *BT; + public CheckerV2<check::Location> { + mutable llvm::OwningPtr<BuiltinBug> BT; public: - ArrayBoundChecker() : BT(0) {} - static void *getTag() { static int x = 0; return &x; } - void visitLocation(CheckerContext &C, const Stmt *S, SVal l, bool isLoad); + void checkLocation(SVal l, bool isLoad, CheckerContext &C) const; }; } -void ento::RegisterArrayBoundChecker(ExprEngine &Eng) { - Eng.registerCheck(new ArrayBoundChecker()); -} - -void ArrayBoundChecker::visitLocation(CheckerContext &C, const Stmt *S, SVal l, - bool isLoad) { +void ArrayBoundChecker::checkLocation(SVal l, bool isLoad, + CheckerContext &C) const { // Check for out of bound array element access. const MemRegion *R = l.getAsRegion(); if (!R) @@ -69,8 +65,8 @@ void ArrayBoundChecker::visitLocation(CheckerContext &C, const Stmt *S, SVal l, return; if (!BT) - BT = new BuiltinBug("Out-of-bound array access", - "Access out-of-bound array element (buffer overflow)"); + BT.reset(new BuiltinBug("Out-of-bound array access", + "Access out-of-bound array element (buffer overflow)")); // FIXME: It would be nice to eventually make this diagnostic more clear, // e.g., by referencing the original declaration or by saying *why* this @@ -80,7 +76,7 @@ void ArrayBoundChecker::visitLocation(CheckerContext &C, const Stmt *S, SVal l, RangedBugReport *report = new RangedBugReport(*BT, BT->getDescription(), N); - report->addRange(S->getSourceRange()); + report->addRange(C.getStmt()->getSourceRange()); C.EmitReport(report); return; } @@ -90,3 +86,7 @@ void ArrayBoundChecker::visitLocation(CheckerContext &C, const Stmt *S, SVal l, assert(StInBound); C.addTransition(StInBound); } + +void ento::registerArrayBoundChecker(CheckerManager &mgr) { + mgr.registerChecker<ArrayBoundChecker>(); +} diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td index df959b85c2..ea1686a0b5 100644 --- a/lib/StaticAnalyzer/Checkers/Checkers.td +++ b/lib/StaticAnalyzer/Checkers/Checkers.td @@ -179,6 +179,11 @@ def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, HelpText<"Check for an out-of-bound pointer being returned to callers">, DescFile<"ReturnPointerRangeChecker.cpp">; +def ArrayBoundChecker : Checker<"ArrayBound">, + InPackage<CoreExperimental>, + HelpText<"Check for an out-of-bound pointer being returned to callers">, + DescFile<"ArrayBoundChecker.cpp">; + def ObjCDeallocChecker : Checker<"Dealloc">, InPackage<CocoaExperimental>, HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">, diff --git a/lib/StaticAnalyzer/Checkers/ExperimentalChecks.cpp b/lib/StaticAnalyzer/Checkers/ExperimentalChecks.cpp index bcae801e29..ebd128b1c5 100644 --- a/lib/StaticAnalyzer/Checkers/ExperimentalChecks.cpp +++ b/lib/StaticAnalyzer/Checkers/ExperimentalChecks.cpp @@ -29,6 +29,5 @@ void ento::RegisterExperimentalInternalChecks(ExprEngine &Eng) { // These are internal checks that should eventually migrate to // RegisterInternalChecks() once they have been further tested. - RegisterArrayBoundChecker(Eng); RegisterCastSizeChecker(Eng); } diff --git a/lib/StaticAnalyzer/Checkers/InternalChecks.h b/lib/StaticAnalyzer/Checkers/InternalChecks.h index f6246f4fb1..9ccc7b42d7 100644 --- a/lib/StaticAnalyzer/Checkers/InternalChecks.h +++ b/lib/StaticAnalyzer/Checkers/InternalChecks.h @@ -23,7 +23,6 @@ class ExprEngine; // Foundational checks that handle basic semantics. void RegisterAdjustedReturnValueChecker(ExprEngine &Eng); -void RegisterArrayBoundChecker(ExprEngine &Eng); void RegisterArrayBoundCheckerV2(ExprEngine &Eng); void RegisterAttrNonNullChecker(ExprEngine &Eng); void RegisterBuiltinFunctionChecker(ExprEngine &Eng); diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 6cec133b0b..12674c544e 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/test/Analysis/misc-ps-region-store.m @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core.experimental.IdempotentOps -analyzer-checker=core.experimental.CastToStruct -analyzer-checker=core.experimental.ReturnPtrRange -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-checker=core.experimental.IdempotentOps -analyzer-checker=core.experimental.CastToStruct -analyzer-checker=core.experimental.ReturnPtrRange -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core.experimental.IdempotentOps -analyzer-checker=core.experimental.CastToStruct -analyzer-checker=core.experimental.ReturnPtrRange -analyzer-checker=core.experimental.ReturnPtrRange -analyzer-checker=core.experimental.ArrayBound -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-checker=core.experimental.IdempotentOps -analyzer-checker=core.experimental.CastToStruct -analyzer-checker=core.experimental.ReturnPtrRange -analyzer-checker=core.experimental.ArrayBound -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s typedef long unsigned int size_t; void *memcpy(void *, const void *, size_t); diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c index 3b261bbb5c..63361f59a4 100644 --- a/test/Analysis/outofbound.c +++ b/test/Analysis/outofbound.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-experimental-internal-checks -analyzer-experimental-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s +// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core.experimental.ArrayBound -analyzer-experimental-internal-checks -analyzer-experimental-checks -analyzer-check-objc-mem -analyzer-store=region -verify %s typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); diff --git a/test/Analysis/rdar-6541136-region.c b/test/Analysis/rdar-6541136-region.c index 82232c6bb9..e752783510 100644 --- a/test/Analysis/rdar-6541136-region.c +++ b/test/Analysis/rdar-6541136-region.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region %s +// RUN: %clang_cc1 -verify -analyze -analyzer-checker=core.experimental.ArrayBound -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region %s struct tea_cheese { unsigned magic; }; typedef struct tea_cheese kernel_tea_cheese_t; |