22 using namespace clang;
26 class ArrayBoundChecker :
27 public Checker<check::Location> {
28 mutable std::unique_ptr<BuiltinBug> BT;
31 void checkLocation(SVal l,
bool isLoad,
const Stmt* S,
32 CheckerContext &C)
const;
36 void ArrayBoundChecker::checkLocation(SVal l,
bool isLoad,
const Stmt* LoadS,
37 CheckerContext &C)
const {
39 const MemRegion *R = l.getAsRegion();
43 const ElementRegion *ER = dyn_cast<ElementRegion>(R);
48 DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
52 if (Idx.isZeroConstant())
59 state, ER->getSuperRegion(),
C.getSValBuilder(), ER->getValueType());
62 std::tie(StInBound, StOutBound) =
state->assumeInBoundDual(Idx, ElementCount);
63 if (StOutBound && !StInBound) {
64 ExplodedNode *N =
C.generateErrorNode(StOutBound);
69 BT.reset(
new BuiltinBug(
70 this,
"Out-of-bound array access",
71 "Access out-of-bound array element (buffer overflow)"));
79 std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
82 C.emitReport(std::move(report));
88 C.addTransition(StInBound);
91 void ento::registerArrayBoundChecker(CheckerManager &mgr) {
92 mgr.registerChecker<ArrayBoundChecker>();
95 bool ento::shouldRegisterArrayBoundChecker(
const CheckerManager &mgr) {