diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp index 3c04983df443..fc35082705fa 100644 --- a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp @@ -90,6 +90,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" +#include "llvm/ADT/StringExtras.h" using namespace clang; using namespace ento; @@ -149,6 +150,10 @@ public: CASE(Kind::Released) CASE(Kind::Escaped) } + if (ErrorSym) { + OS << " ErrorSym: "; + ErrorSym->dumpToStream(OS); + } } LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); } @@ -314,6 +319,17 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call, // Function returns an open handle. if (hasFuchsiaAttr<AcquireHandleAttr>(FuncDecl)) { SymbolRef RetSym = Call.getReturnValue().getAsSymbol(); + Notes.push_back([RetSym, FuncDecl](BugReport &BR) -> std::string { + auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR); + if (auto IsInteresting = PathBR->getInterestingnessKind(RetSym)) { + std::string SBuf; + llvm::raw_string_ostream OS(SBuf); + OS << "Function '" << FuncDecl->getNameAsString() + << "' returns an open handle"; + return OS.str(); + } else + return ""; + }); State = State->set<HStateMap>(RetSym, HandleState::getMaybeAllocated(nullptr)); } @@ -322,6 +338,7 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call, if (Arg >= FuncDecl->getNumParams()) break; const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg); + unsigned ParamDiagIdx = PVD->getFunctionScopeIndex() + 1; SymbolRef Handle = getFuchsiaHandleSymbol(PVD->getType(), Call.getArgSVal(Arg), State); if (!Handle) @@ -335,20 +352,28 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call, reportDoubleRelease(Handle, Call.getArgSourceRange(Arg), C); return; } else { - Notes.push_back([Handle](BugReport &BR) { + Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string { auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR); if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) { - return "Handle released here."; + std::string SBuf; + llvm::raw_string_ostream OS(SBuf); + OS << "Handle released through " << ParamDiagIdx + << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter"; + return OS.str(); } else return ""; }); State = State->set<HStateMap>(Handle, HandleState::getReleased()); } } else if (hasFuchsiaAttr<AcquireHandleAttr>(PVD)) { - Notes.push_back([Handle](BugReport &BR) { + Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string { auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR); if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) { - return "Handle allocated here."; + std::string SBuf; + llvm::raw_string_ostream OS(SBuf); + OS << "Handle allocated through " << ParamDiagIdx + << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter"; + return OS.str(); } else return ""; }); @@ -358,8 +383,8 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call, } const NoteTag *T = nullptr; if (!Notes.empty()) { - T = C.getNoteTag( - [this, Notes{std::move(Notes)}](BugReport &BR) -> std::string { + T = C.getNoteTag([this, Notes{std::move(Notes)}]( + PathSensitiveBugReport &BR) -> std::string { if (&BR.getBugType() != &UseAfterReleaseBugType && &BR.getBugType() != &LeakBugType && &BR.getBugType() != &DoubleReleaseBugType) @@ -381,7 +406,13 @@ void FuchsiaHandleChecker::checkDeadSymbols(SymbolReaper &SymReaper, SmallVector<SymbolRef, 2> LeakedSyms; HStateMapTy TrackedHandles = State->get<HStateMap>(); for (auto &CurItem : TrackedHandles) { - if (!SymReaper.isDead(CurItem.first)) + SymbolRef ErrorSym = CurItem.second.getErrorSym(); + // Keeping zombie handle symbols. In case the error symbol is dying later + // than the handle symbol we might produce spurious leak warnings (in case + // we find out later from the status code that the handle allocation failed + // in the first place). + if (!SymReaper.isDead(CurItem.first) || + (ErrorSym && !SymReaper.isDead(ErrorSym))) continue; if (CurItem.second.isAllocated() || CurItem.second.maybeAllocated()) LeakedSyms.push_back(CurItem.first); @@ -535,7 +566,7 @@ void ento::registerFuchsiaHandleChecker(CheckerManager &mgr) { mgr.registerChecker<FuchsiaHandleChecker>(); } -bool ento::shouldRegisterFuchsiaHandleChecker(const LangOptions &LO) { +bool ento::shouldRegisterFuchsiaHandleChecker(const CheckerManager &mgr) { return true; } |