balazske created this revision. Herald added subscribers: cfe-commits, gamesh411, Szelethus, dkrupp. Herald added a project: clang.
Use of evalCall is replaced by preCall and postCall. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D69662 Files: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -49,22 +49,21 @@ } }; -class StreamChecker : public Checker<eval::Call, - check::DeadSymbols > { +class StreamChecker + : public Checker<check::PreCall, check::PostCall, check::DeadSymbols> { mutable std::unique_ptr<BuiltinBug> BT_nullfp, BT_illegalwhence, BT_doubleclose, BT_ResourceLeak; public: - bool evalCall(const CallEvent &Call, CheckerContext &C) const; + void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; private: using FnCheck = std::function<void(const StreamChecker *, const CallEvent &, CheckerContext &)>; - CallDescriptionMap<FnCheck> Callbacks = { - {{"fopen"}, &StreamChecker::evalFopen}, - {{"tmpfile"}, &StreamChecker::evalFopen}, + CallDescriptionMap<FnCheck> PreCallbacks = { {{"fclose", 1}, &StreamChecker::evalFclose}, {{"fread", 4}, std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 3)}, @@ -89,10 +88,17 @@ std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}, }; + CallDescriptionMap<FnCheck> PostCallbacks = { + {{"fopen"}, &StreamChecker::evalFopen}, + {{"tmpfile"}, &StreamChecker::evalFopen}, + }; + void evalFopen(const CallEvent &Call, CheckerContext &C) const; void evalFclose(const CallEvent &Call, CheckerContext &C) const; void evalFseek(const CallEvent &Call, CheckerContext &C) const; + void checkCall(const CallEvent &Call, CheckerContext &C, + const CallDescriptionMap<FnCheck> &Callbacks) const; void checkArgNullStream(const CallEvent &Call, CheckerContext &C, unsigned ArgI) const; bool checkNullStream(SVal SV, CheckerContext &C, @@ -107,29 +113,38 @@ REGISTER_MAP_WITH_PROGRAMSTATE(StreamMap, SymbolRef, StreamState) +void StreamChecker::checkPreCall(const CallEvent &Call, + CheckerContext &C) const { + checkCall(Call, C, PreCallbacks); +} + +void StreamChecker::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { + checkCall(Call, C, PostCallbacks); +} -bool StreamChecker::evalCall(const CallEvent &Call, CheckerContext &C) const { +void StreamChecker::checkCall( + const CallEvent &Call, CheckerContext &C, + const CallDescriptionMap<FnCheck> &Callbacks) const { const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl()); if (!FD || FD->getKind() != Decl::Function) - return false; + return; // Recognize "global C functions" with only integral or pointer arguments // (and matching name) as stream functions. if (!Call.isGlobalCFunction()) - return false; + return; for (auto P : Call.parameters()) { QualType T = P->getType(); if (!T->isIntegralOrEnumerationType() && !T->isPointerType()) - return false; + return; } const FnCheck *Callback = Callbacks.lookup(Call); if (!Callback) - return false; + return; (*Callback)(this, Call, C); - - return C.isDifferent(); } void StreamChecker::evalFopen(const CallEvent &Call, CheckerContext &C) const {
Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -49,22 +49,21 @@ } }; -class StreamChecker : public Checker<eval::Call, - check::DeadSymbols > { +class StreamChecker + : public Checker<check::PreCall, check::PostCall, check::DeadSymbols> { mutable std::unique_ptr<BuiltinBug> BT_nullfp, BT_illegalwhence, BT_doubleclose, BT_ResourceLeak; public: - bool evalCall(const CallEvent &Call, CheckerContext &C) const; + void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + void checkPostCall(const CallEvent &Call, CheckerContext &C) const; void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const; private: using FnCheck = std::function<void(const StreamChecker *, const CallEvent &, CheckerContext &)>; - CallDescriptionMap<FnCheck> Callbacks = { - {{"fopen"}, &StreamChecker::evalFopen}, - {{"tmpfile"}, &StreamChecker::evalFopen}, + CallDescriptionMap<FnCheck> PreCallbacks = { {{"fclose", 1}, &StreamChecker::evalFclose}, {{"fread", 4}, std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 3)}, @@ -89,10 +88,17 @@ std::bind(&StreamChecker::checkArgNullStream, _1, _2, _3, 0)}, }; + CallDescriptionMap<FnCheck> PostCallbacks = { + {{"fopen"}, &StreamChecker::evalFopen}, + {{"tmpfile"}, &StreamChecker::evalFopen}, + }; + void evalFopen(const CallEvent &Call, CheckerContext &C) const; void evalFclose(const CallEvent &Call, CheckerContext &C) const; void evalFseek(const CallEvent &Call, CheckerContext &C) const; + void checkCall(const CallEvent &Call, CheckerContext &C, + const CallDescriptionMap<FnCheck> &Callbacks) const; void checkArgNullStream(const CallEvent &Call, CheckerContext &C, unsigned ArgI) const; bool checkNullStream(SVal SV, CheckerContext &C, @@ -107,29 +113,38 @@ REGISTER_MAP_WITH_PROGRAMSTATE(StreamMap, SymbolRef, StreamState) +void StreamChecker::checkPreCall(const CallEvent &Call, + CheckerContext &C) const { + checkCall(Call, C, PreCallbacks); +} + +void StreamChecker::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { + checkCall(Call, C, PostCallbacks); +} -bool StreamChecker::evalCall(const CallEvent &Call, CheckerContext &C) const { +void StreamChecker::checkCall( + const CallEvent &Call, CheckerContext &C, + const CallDescriptionMap<FnCheck> &Callbacks) const { const auto *FD = dyn_cast_or_null<FunctionDecl>(Call.getDecl()); if (!FD || FD->getKind() != Decl::Function) - return false; + return; // Recognize "global C functions" with only integral or pointer arguments // (and matching name) as stream functions. if (!Call.isGlobalCFunction()) - return false; + return; for (auto P : Call.parameters()) { QualType T = P->getType(); if (!T->isIntegralOrEnumerationType() && !T->isPointerType()) - return false; + return; } const FnCheck *Callback = Callbacks.lookup(Call); if (!Callback) - return false; + return; (*Callback)(this, Call, C); - - return C.isDifferent(); } void StreamChecker::evalFopen(const CallEvent &Call, CheckerContext &C) const {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits