diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp | 74 |
1 files changed, 43 insertions, 31 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp index de6da4f..fbc57d3 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp @@ -20,7 +20,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/GRStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Decl.h" #include "clang/AST/Type.h" @@ -117,16 +117,28 @@ public: CheckerContext &C) const; private: - const GRState *handleAssign(const GRState *state, const Expr *lexp, - const Expr *rexp, const LocationContext *LC) const; - const GRState *handleAssign(const GRState *state, const MemRegion *MR, - const Expr *rexp, const LocationContext *LC) const; - const GRState *invalidateIterators(const GRState *state, const MemRegion *MR, - const MemberExpr *ME) const; + const ProgramState *handleAssign(const ProgramState *state, + const Expr *lexp, + const Expr *rexp, + const LocationContext *LC) const; + + const ProgramState *handleAssign(const ProgramState *state, + const MemRegion *MR, + const Expr *rexp, + const LocationContext *LC) const; + + const ProgramState *invalidateIterators(const ProgramState *state, + const MemRegion *MR, + const MemberExpr *ME) const; + void checkExpr(CheckerContext &C, const Expr *E) const; + void checkArgs(CheckerContext &C, const CallExpr *CE) const; - const MemRegion *getRegion(const GRState *state, const Expr *E, - const LocationContext *LC) const; + + const MemRegion *getRegion(const ProgramState *state, + const Expr *E, + const LocationContext *LC) const; + const DeclRefExpr *getDeclRefExpr(const Expr *E) const; }; @@ -139,8 +151,8 @@ public: namespace clang { namespace ento { template <> - struct GRStateTrait<IteratorState> - : public GRStatePartialTrait<IteratorState::EntryMap> { + struct ProgramStateTrait<IteratorState> + : public ProgramStatePartialTrait<IteratorState::EntryMap> { static void *GDMIndex() { return IteratorsChecker::getTag(); } }; } @@ -162,7 +174,7 @@ static RefKind getTemplateKind(const NamedDecl *td) { || nameSpace->getName() != "std") return NoKind; - llvm::StringRef name = td->getName(); + StringRef name = td->getName(); return llvm::StringSwitch<RefKind>(name) .Cases("vector", "deque", VectorKind) .Default(NoKind); @@ -215,7 +227,7 @@ static RefKind getTemplateKind(QualType T) { // Iterate through our map and invalidate any iterators that were // initialized fromt the specified instance MemRegion. -const GRState *IteratorsChecker::invalidateIterators(const GRState *state, +const ProgramState *IteratorsChecker::invalidateIterators(const ProgramState *state, const MemRegion *MR, const MemberExpr *ME) const { IteratorState::EntryMap Map = state->get<IteratorState>(); if (Map.isEmpty()) @@ -234,7 +246,7 @@ const GRState *IteratorsChecker::invalidateIterators(const GRState *state, } // Handle assigning to an iterator where we don't have the LValue MemRegion. -const GRState *IteratorsChecker::handleAssign(const GRState *state, +const ProgramState *IteratorsChecker::handleAssign(const ProgramState *state, const Expr *lexp, const Expr *rexp, const LocationContext *LC) const { // Skip the cast if present. if (const MaterializeTemporaryExpr *M @@ -259,7 +271,7 @@ const GRState *IteratorsChecker::handleAssign(const GRState *state, } // handle assigning to an iterator -const GRState *IteratorsChecker::handleAssign(const GRState *state, +const ProgramState *IteratorsChecker::handleAssign(const ProgramState *state, const MemRegion *MR, const Expr *rexp, const LocationContext *LC) const { // Assume unknown until we find something definite. state = state->set<IteratorState>(MR, RefState::getUnknown()); @@ -287,7 +299,7 @@ const GRState *IteratorsChecker::handleAssign(const GRState *state, return state; // Finally, see if it is one of the calls that will create // a valid iterator and mark it if so, else mark as Unknown. - llvm::StringRef mName = ME->getMemberDecl()->getName(); + StringRef mName = ME->getMemberDecl()->getName(); if (llvm::StringSwitch<bool>(mName) .Cases("begin", "insert", "erase", true).Default(false)) { @@ -364,7 +376,7 @@ const DeclRefExpr *IteratorsChecker::getDeclRefExpr(const Expr *E) const { } // Get the MemRegion associated with the expresssion. -const MemRegion *IteratorsChecker::getRegion(const GRState *state, +const MemRegion *IteratorsChecker::getRegion(const ProgramState *state, const Expr *E, const LocationContext *LC) const { const DeclRefExpr *DRE = getDeclRefExpr(E); if (!DRE) @@ -382,7 +394,7 @@ const MemRegion *IteratorsChecker::getRegion(const GRState *state, // use those nodes. We also cannot create multiple nodes at one ProgramPoint // with the same tag. void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const { - const GRState *state = C.getState(); + const ProgramState *state = C.getState(); const MemRegion *MR = getRegion(state, E, C.getPredecessor()->getLocationContext()); if (!MR) @@ -410,7 +422,7 @@ void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const { "container to its container"; } - EnhancedBugReport *R = new EnhancedBugReport(*BT_Invalid, msg, N); + BugReport *R = new BugReport(*BT_Invalid, msg, N); R->addRange(getDeclRefExpr(E)->getSourceRange()); C.EmitReport(R); } @@ -422,7 +434,7 @@ void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const { const_cast<IteratorsChecker*>(this)->BT_Undefined = new BuiltinBug("Use of iterator that is not defined"); - EnhancedBugReport *R = new EnhancedBugReport(*BT_Undefined, + BugReport *R = new BugReport(*BT_Undefined, BT_Undefined->getDescription(), N); R->addRange(getDeclRefExpr(E)->getSourceRange()); C.EmitReport(R); @@ -455,7 +467,7 @@ void IteratorsChecker::checkPreStmt(const CXXOperatorCallExpr *OCE, CheckerContext &C) const { const LocationContext *LC = C.getPredecessor()->getLocationContext(); - const GRState *state = C.getState(); + const ProgramState *state = C.getState(); OverloadedOperatorKind Kind = OCE->getOperator(); if (Kind == OO_Equal) { checkExpr(C, OCE->getArg(1)); @@ -491,8 +503,8 @@ void IteratorsChecker::checkPreStmt(const CXXOperatorCallExpr *OCE, new BuiltinBug( "Cannot compare iterators from different containers"); - EnhancedBugReport *R = new EnhancedBugReport(*BT_Incompatible, - BT_Incompatible->getDescription(), N); + BugReport *R = new BugReport(*BT_Incompatible, + BT_Incompatible->getDescription(), N); R->addRange(OCE->getSourceRange()); C.EmitReport(R); } @@ -505,14 +517,14 @@ void IteratorsChecker::checkPreStmt(const CXXOperatorCallExpr *OCE, // uninitialized ones as Undefined. void IteratorsChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const { - const Decl* D = *DS->decl_begin(); - const VarDecl* VD = dyn_cast<VarDecl>(D); + const Decl *D = *DS->decl_begin(); + const VarDecl *VD = dyn_cast<VarDecl>(D); // Only care about iterators. if (getTemplateKind(VD->getType()) != VectorIteratorKind) return; // Get the MemRegion associated with the iterator and mark it as Undefined. - const GRState *state = C.getState(); + const ProgramState *state = C.getState(); Loc VarLoc = state->getLValue(VD, C.getPredecessor()->getLocationContext()); const MemRegion *MR = VarLoc.getAsRegion(); if (!MR) @@ -520,7 +532,7 @@ void IteratorsChecker::checkPreStmt(const DeclStmt *DS, state = state->set<IteratorState>(MR, RefState::getUndefined()); // if there is an initializer, handle marking Valid if a proper initializer - const Expr* InitEx = VD->getInit(); + const Expr *InitEx = VD->getInit(); if (InitEx) { // FIXME: This is too syntactic. Since 'InitEx' will be analyzed first // it should resolve to an SVal that we can check for validity @@ -544,8 +556,8 @@ void IteratorsChecker::checkPreStmt(const DeclStmt *DS, namespace { struct CalledReserved {}; } namespace clang { namespace ento { -template<> struct GRStateTrait<CalledReserved> - : public GRStatePartialTrait<llvm::ImmutableSet<const MemRegion*> > { +template<> struct ProgramStateTrait<CalledReserved> + : public ProgramStatePartialTrait<llvm::ImmutableSet<const MemRegion*> > { static void *GDMIndex() { static int index = 0; return &index; } }; }} @@ -571,8 +583,8 @@ void IteratorsChecker::checkPreStmt(const CXXMemberCallExpr *MCE, return; // If we are calling a function that invalidates iterators, mark them // appropriately by finding matching instances. - const GRState *state = C.getState(); - llvm::StringRef mName = ME->getMemberDecl()->getName(); + const ProgramState *state = C.getState(); + StringRef mName = ME->getMemberDecl()->getName(); if (llvm::StringSwitch<bool>(mName) .Cases("insert", "reserve", "push_back", true) .Cases("erase", "pop_back", "clear", "resize", true) |