diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index dc6bd4f1544e8..ab4c9fafae1db 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -94,15 +94,15 @@ class StreamChecker : public CheckergetAsSymbol(); @@ -208,7 +207,8 @@ void StreamChecker::evalFreopen(const CallEvent &Call, void StreamChecker::evalFclose(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); - if (checkDoubleClose(Call, C, State)) + State = checkDoubleClose(Call, C, State); + if (State) C.addTransition(State); } @@ -219,30 +219,31 @@ void StreamChecker::evalFseek(const CallEvent &Call, CheckerContext &C) const { ProgramStateRef State = C.getState(); - bool StateChanged = checkNullStream(Call.getArgSVal(0), C, State); - // Check if error was generated. - if (C.isDifferent()) + State = checkNullStream(Call.getArgSVal(0), C, State); + if (!State) return; - // Check the legality of the 'whence' argument of 'fseek'. - checkFseekWhence(State->getSVal(AE2, C.getLocationContext()), C, State); + State = + checkFseekWhence(State->getSVal(AE2, C.getLocationContext()), C, State); + if (!State) + return; - if (!C.isDifferent() && StateChanged) - C.addTransition(State); + C.addTransition(State); } void StreamChecker::checkArgNullStream(const CallEvent &Call, CheckerContext &C, unsigned ArgI) const { ProgramStateRef State = C.getState(); - if (checkNullStream(Call.getArgSVal(ArgI), C, State)) + State = checkNullStream(Call.getArgSVal(ArgI), C, State); + if (State) C.addTransition(State); } -bool StreamChecker::checkNullStream(SVal SV, CheckerContext &C, - ProgramStateRef &State) const { +ProgramStateRef StreamChecker::checkNullStream(SVal SV, CheckerContext &C, + ProgramStateRef State) const { Optional DV = SV.getAs(); if (!DV) - return false; + return State; ConstraintManager &CM = C.getConstraintManager(); ProgramStateRef StateNotNull, StateNull; @@ -256,26 +257,22 @@ bool StreamChecker::checkNullStream(SVal SV, CheckerContext &C, C.emitReport(std::make_unique( *BT_nullfp, BT_nullfp->getDescription(), N)); } - return false; - } - - if (StateNotNull) { - State = StateNotNull; - return true; + return nullptr; } - return false; + return StateNotNull; } -void StreamChecker::checkFseekWhence(SVal SV, CheckerContext &C, - ProgramStateRef &State) const { +// Check the legality of the 'whence' argument of 'fseek'. +ProgramStateRef StreamChecker::checkFseekWhence(SVal SV, CheckerContext &C, + ProgramStateRef State) const { Optional CI = SV.getAs(); if (!CI) - return; + return State; int64_t X = CI->getValue().getSExtValue(); if (X >= 0 && X <= 2) - return; + return State; if (ExplodedNode *N = C.generateNonFatalErrorNode(State)) { if (!BT_illegalwhence) @@ -285,20 +282,24 @@ void StreamChecker::checkFseekWhence(SVal SV, CheckerContext &C, "SEEK_SET, SEEK_END, or SEEK_CUR.")); C.emitReport(std::make_unique( *BT_illegalwhence, BT_illegalwhence->getDescription(), N)); + return nullptr; } + + return State; } -bool StreamChecker::checkDoubleClose(const CallEvent &Call, CheckerContext &C, - ProgramStateRef &State) const { +ProgramStateRef StreamChecker::checkDoubleClose(const CallEvent &Call, + CheckerContext &C, + ProgramStateRef State) const { SymbolRef Sym = Call.getArgSVal(0).getAsSymbol(); if (!Sym) - return false; + return State; const StreamState *SS = State->get(Sym); // If the file stream is not tracked, return. if (!SS) - return false; + return State; // Check: Double close a File Descriptor could cause undefined behaviour. // Conforming to man-pages @@ -311,14 +312,16 @@ bool StreamChecker::checkDoubleClose(const CallEvent &Call, CheckerContext &C, " closed. Cause undefined behaviour.")); C.emitReport(std::make_unique( *BT_doubleclose, BT_doubleclose->getDescription(), N)); + return nullptr; } - return false; + + return State; } // Close the File Descriptor. State = State->set(Sym, StreamState::getClosed()); - return true; + return State; } void StreamChecker::checkDeadSymbols(SymbolReaper &SymReaper,