diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp | 58 |
1 files changed, 14 insertions, 44 deletions
diff --git a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp index 8d380ed1b93d..7cbe271dfbf9 100644 --- a/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp +++ b/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp @@ -17,6 +17,7 @@ #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include <utility> @@ -51,10 +52,13 @@ class SimpleStreamChecker : public Checker<check::PostCall, check::PreCall, check::DeadSymbols, check::PointerEscape> { - CallDescription OpenFn, CloseFn; + const CallDescription OpenFn{{"fopen"}, 2}; + const CallDescription CloseFn{{"fclose"}, 1}; - std::unique_ptr<BugType> DoubleCloseBugType; - std::unique_ptr<BugType> LeakBugType; + const BugType DoubleCloseBugType{this, "Double fclose", + "Unix Stream API Error"}; + const BugType LeakBugType{this, "Resource Leak", "Unix Stream API Error", + /*SuppressOnSink=*/true}; void reportDoubleClose(SymbolRef FileDescSym, const CallEvent &Call, @@ -66,8 +70,6 @@ class SimpleStreamChecker : public Checker<check::PostCall, bool guaranteedNotToCloseFile(const CallEvent &Call) const; public: - SimpleStreamChecker(); - /// Process fopen. void checkPostCall(const CallEvent &Call, CheckerContext &C) const; /// Process fclose. @@ -88,38 +90,12 @@ public: /// state. Let's store it in the ProgramState. REGISTER_MAP_WITH_PROGRAMSTATE(StreamMap, SymbolRef, StreamState) -namespace { -class StopTrackingCallback final : public SymbolVisitor { - ProgramStateRef state; -public: - StopTrackingCallback(ProgramStateRef st) : state(std::move(st)) {} - ProgramStateRef getState() const { return state; } - - bool VisitSymbol(SymbolRef sym) override { - state = state->remove<StreamMap>(sym); - return true; - } -}; -} // end anonymous namespace - -SimpleStreamChecker::SimpleStreamChecker() - : OpenFn("fopen"), CloseFn("fclose", 1) { - // Initialize the bug types. - DoubleCloseBugType.reset( - new BugType(this, "Double fclose", "Unix Stream API Error")); - - // Sinks are higher importance bugs as well as calls to assert() or exit(0). - LeakBugType.reset( - new BugType(this, "Resource Leak", "Unix Stream API Error", - /*SuppressOnSink=*/true)); -} - void SimpleStreamChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { if (!Call.isGlobalCFunction()) return; - if (!Call.isCalled(OpenFn)) + if (!OpenFn.matches(Call)) return; // Get the symbolic value corresponding to the file handle. @@ -138,7 +114,7 @@ void SimpleStreamChecker::checkPreCall(const CallEvent &Call, if (!Call.isGlobalCFunction()) return; - if (!Call.isCalled(CloseFn)) + if (!CloseFn.matches(Call)) return; // Get the symbolic value corresponding to the file handle. @@ -176,13 +152,11 @@ void SimpleStreamChecker::checkDeadSymbols(SymbolReaper &SymReaper, ProgramStateRef State = C.getState(); SymbolVector LeakedStreams; StreamMapTy TrackedStreams = State->get<StreamMap>(); - for (StreamMapTy::iterator I = TrackedStreams.begin(), - E = TrackedStreams.end(); I != E; ++I) { - SymbolRef Sym = I->first; + for (auto [Sym, StreamStatus] : TrackedStreams) { bool IsSymDead = SymReaper.isDead(Sym); // Collect leaked symbols. - if (isLeaked(Sym, I->second, IsSymDead, State)) + if (isLeaked(Sym, StreamStatus, IsSymDead, State)) LeakedStreams.push_back(Sym); // Remove the dead symbol from the streams map. @@ -207,7 +181,7 @@ void SimpleStreamChecker::reportDoubleClose(SymbolRef FileDescSym, // Generate the report. auto R = std::make_unique<PathSensitiveBugReport>( - *DoubleCloseBugType, "Closing a previously closed file stream", ErrNode); + DoubleCloseBugType, "Closing a previously closed file stream", ErrNode); R->addRange(Call.getSourceRange()); R->markInteresting(FileDescSym); C.emitReport(std::move(R)); @@ -220,7 +194,7 @@ void SimpleStreamChecker::reportLeaks(ArrayRef<SymbolRef> LeakedStreams, // TODO: Identify the leaked file descriptor. for (SymbolRef LeakedStream : LeakedStreams) { auto R = std::make_unique<PathSensitiveBugReport>( - *LeakBugType, "Opened file is never closed; potential resource leak", + LeakBugType, "Opened file is never closed; potential resource leak", ErrNode); R->markInteresting(LeakedStream); C.emitReport(std::move(R)); @@ -254,11 +228,7 @@ SimpleStreamChecker::checkPointerEscape(ProgramStateRef State, return State; } - for (InvalidatedSymbols::const_iterator I = Escaped.begin(), - E = Escaped.end(); - I != E; ++I) { - SymbolRef Sym = *I; - + for (SymbolRef Sym : Escaped) { // The symbol escaped. Optimistically, assume that the corresponding file // handle will be closed somewhere else. State = State->remove<StreamMap>(Sym); |