diff options
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/StreamChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/StreamChecker.cpp | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index 731dd66..c06ba7c 100644 --- a/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -104,15 +104,8 @@ private: } // end anonymous namespace -namespace clang { -namespace ento { - template <> - struct ProgramStateTrait<StreamState> - : public ProgramStatePartialTrait<llvm::ImmutableMap<SymbolRef, StreamState> > { - static void *GDMIndex() { static int x; return &x; } - }; -} -} +REGISTER_MAP_WITH_PROGRAMSTATE(StreamMap, SymbolRef, StreamState) + bool StreamChecker::evalCall(const CallExpr *CE, CheckerContext &C) const { const FunctionDecl *FD = C.getCalleeDecl(CE); @@ -219,11 +212,11 @@ void StreamChecker::Tmpfile(CheckerContext &C, const CallExpr *CE) const { void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const { ProgramStateRef state = C.getState(); - unsigned Count = C.getCurrentBlockCount(); SValBuilder &svalBuilder = C.getSValBuilder(); const LocationContext *LCtx = C.getPredecessor()->getLocationContext(); DefinedSVal RetVal = - cast<DefinedSVal>(svalBuilder.getConjuredSymbolVal(0, CE, LCtx, Count)); + cast<DefinedSVal>(svalBuilder.conjureSymbolVal(0, CE, LCtx, + C.blockCount())); state = state->BindExpr(CE, C.getLocationContext(), RetVal); ConstraintManager &CM = C.getConstraintManager(); @@ -235,9 +228,9 @@ void StreamChecker::OpenFileAux(CheckerContext &C, const CallExpr *CE) const { if (SymbolRef Sym = RetVal.getAsSymbol()) { // if RetVal is not NULL, set the symbol's state to Opened. stateNotNull = - stateNotNull->set<StreamState>(Sym,StreamState::getOpened(CE)); + stateNotNull->set<StreamMap>(Sym,StreamState::getOpened(CE)); stateNull = - stateNull->set<StreamState>(Sym, StreamState::getOpenFailed(CE)); + stateNull->set<StreamMap>(Sym, StreamState::getOpenFailed(CE)); C.addTransition(stateNotNull); C.addTransition(stateNull); @@ -287,7 +280,7 @@ void StreamChecker::Fseek(CheckerContext &C, const CallExpr *CE) const { "SEEK_SET, SEEK_END, or SEEK_CUR.")); BugReport *R = new BugReport(*BT_illegalwhence, BT_illegalwhence->getDescription(), N); - C.EmitReport(R); + C.emitReport(R); } } @@ -363,7 +356,7 @@ ProgramStateRef StreamChecker::CheckNullStream(SVal SV, ProgramStateRef state, BT_nullfp.reset(new BuiltinBug("NULL stream pointer", "Stream pointer might be NULL.")); BugReport *R =new BugReport(*BT_nullfp, BT_nullfp->getDescription(), N); - C.EmitReport(R); + C.emitReport(R); } return 0; } @@ -378,7 +371,7 @@ ProgramStateRef StreamChecker::CheckDoubleClose(const CallExpr *CE, if (!Sym) return state; - const StreamState *SS = state->get<StreamState>(Sym); + const StreamState *SS = state->get<StreamMap>(Sym); // If the file stream is not tracked, return. if (!SS) @@ -395,22 +388,24 @@ ProgramStateRef StreamChecker::CheckDoubleClose(const CallExpr *CE, " closed. Cause undefined behaviour.")); BugReport *R = new BugReport(*BT_doubleclose, BT_doubleclose->getDescription(), N); - C.EmitReport(R); + C.emitReport(R); } return NULL; } // Close the File Descriptor. - return state->set<StreamState>(Sym, StreamState::getClosed(CE)); + return state->set<StreamMap>(Sym, StreamState::getClosed(CE)); } void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const { + // TODO: Clean up the state. for (SymbolReaper::dead_iterator I = SymReaper.dead_begin(), E = SymReaper.dead_end(); I != E; ++I) { SymbolRef Sym = *I; ProgramStateRef state = C.getState(); - const StreamState *SS = state->get<StreamState>(Sym); + const StreamState *SS = state->get<StreamMap>(Sym); + // TODO: Shouldn't we have a continue here? if (!SS) return; @@ -422,7 +417,7 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, "Opened File never closed. Potential Resource leak.")); BugReport *R = new BugReport(*BT_ResourceLeak, BT_ResourceLeak->getDescription(), N); - C.EmitReport(R); + C.emitReport(R); } } } @@ -430,10 +425,9 @@ void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, void StreamChecker::checkEndPath(CheckerContext &Ctx) const { ProgramStateRef state = Ctx.getState(); - typedef llvm::ImmutableMap<SymbolRef, StreamState> SymMap; - SymMap M = state->get<StreamState>(); + StreamMapTy M = state->get<StreamMap>(); - for (SymMap::iterator I = M.begin(), E = M.end(); I != E; ++I) { + for (StreamMapTy::iterator I = M.begin(), E = M.end(); I != E; ++I) { StreamState SS = I->second; if (SS.isOpened()) { ExplodedNode *N = Ctx.addTransition(state); @@ -443,7 +437,7 @@ void StreamChecker::checkEndPath(CheckerContext &Ctx) const { "Opened File never closed. Potential Resource leak.")); BugReport *R = new BugReport(*BT_ResourceLeak, BT_ResourceLeak->getDescription(), N); - Ctx.EmitReport(R); + Ctx.emitReport(R); } } } @@ -460,12 +454,12 @@ void StreamChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const { if (!Sym) return; - const StreamState *SS = state->get<StreamState>(Sym); + const StreamState *SS = state->get<StreamMap>(Sym); if(!SS) return; if (SS->isOpened()) - state = state->set<StreamState>(Sym, StreamState::getEscaped(S)); + state = state->set<StreamMap>(Sym, StreamState::getEscaped(S)); C.addTransition(state); } |