diff options
| author | Gabor Horvath <xazax@google.com> | 2019-11-26 09:17:30 -0800 |
|---|---|---|
| committer | Gabor Horvath <xazax@google.com> | 2019-12-20 12:40:41 -0800 |
| commit | 59878ec8092bef656a71d22261fd3b70651e8318 (patch) | |
| tree | e8a059e5a42a566646adf103139ed816b50cd7aa /clang/lib/StaticAnalyzer | |
| parent | 226a014044d9c99a235de1b4bcef364b61123f37 (diff) | |
| download | bcm5719-llvm-59878ec8092bef656a71d22261fd3b70651e8318.tar.gz bcm5719-llvm-59878ec8092bef656a71d22261fd3b70651e8318.zip | |
[analyzer] Add path notes to FuchsiaHandleCheck.
Differential Revision: https://reviews.llvm.org/D70725
Diffstat (limited to 'clang/lib/StaticAnalyzer')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp index 25eb4f5ba82..861dfef0239 100644 --- a/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp @@ -199,6 +199,28 @@ public: REGISTER_MAP_WITH_PROGRAMSTATE(HStateMap, SymbolRef, HandleState) +static const ExplodedNode *getAcquireSite(const ExplodedNode *N, SymbolRef Sym, + CheckerContext &Ctx) { + ProgramStateRef State = N->getState(); + // When bug type is handle leak, exploded node N does not have state info for + // leaking handle. Get the predecessor of N instead. + if (!State->get<HStateMap>(Sym)) + N = N->getFirstPred(); + + const ExplodedNode *Pred = N; + while (N) { + State = N->getState(); + if (!State->get<HStateMap>(Sym)) { + const HandleState *HState = Pred->getState()->get<HStateMap>(Sym); + if (HState && (HState->isAllocated() || HState->maybeAllocated())) + return N; + } + Pred = N; + N = N->getFirstPred(); + } + return nullptr; +} + /// Returns the symbols extracted from the argument or null if it cannot be /// found. SymbolRef getFuchsiaHandleSymbol(QualType QT, SVal Arg, ProgramStateRef State) { @@ -282,6 +304,7 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call, ProgramStateRef State = C.getState(); + std::vector<std::function<std::string(BugReport & BR)>> Notes; SymbolRef ResultSymbol = nullptr; if (const auto *TypeDefTy = FuncDecl->getReturnType()->getAs<TypedefType>()) if (TypeDefTy->getDecl()->getName() == ErrorTypeName) @@ -310,14 +333,45 @@ void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call, if (HState && HState->isReleased()) { reportDoubleRelease(Handle, Call.getArgSourceRange(Arg), C); return; - } else + } else { + Notes.push_back([Handle](BugReport &BR) { + auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR); + if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) { + return "Handle released here."; + } else + return ""; + }); State = State->set<HStateMap>(Handle, HandleState::getReleased()); + } } else if (hasFuchsiaAttr<AcquireHandleAttr>(PVD)) { + Notes.push_back([Handle](BugReport &BR) { + auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR); + if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) { + return "Handle allocated here."; + } else + return ""; + }); State = State->set<HStateMap>( Handle, HandleState::getMaybeAllocated(ResultSymbol)); } } - C.addTransition(State); + const NoteTag *T = nullptr; + if (!Notes.empty()) { + T = C.getNoteTag( + [this, Notes{std::move(Notes)}](BugReport &BR) -> std::string { + if (&BR.getBugType() != &UseAfterReleaseBugType && + &BR.getBugType() != &LeakBugType && + &BR.getBugType() != &DoubleReleaseBugType) + return ""; + for (auto &Note : Notes) { + std::string Text = Note(BR); + if (!Text.empty()) + return Text; + } + return ""; + }); + } + C.addTransition(State, T); } void FuchsiaHandleChecker::checkDeadSymbols(SymbolReaper &SymReaper, @@ -353,6 +407,7 @@ void FuchsiaHandleChecker::checkDeadSymbols(SymbolReaper &SymReaper, ProgramStateRef FuchsiaHandleChecker::evalAssume(ProgramStateRef State, SVal Cond, bool Assumption) const { + // TODO: add notes about successes/fails for APIs. ConstraintManager &Cmr = State->getConstraintManager(); HStateMapTy TrackedHandles = State->get<HStateMap>(); for (auto &CurItem : TrackedHandles) { @@ -453,7 +508,22 @@ void FuchsiaHandleChecker::reportBug(SymbolRef Sym, ExplodedNode *ErrorNode, if (!ErrorNode) return; - auto R = std::make_unique<PathSensitiveBugReport>(Type, Msg, ErrorNode); + std::unique_ptr<PathSensitiveBugReport> R; + if (Type.isSuppressOnSink()) { + const ExplodedNode *AcquireNode = getAcquireSite(ErrorNode, Sym, C); + if (AcquireNode) { + PathDiagnosticLocation LocUsedForUniqueing = + PathDiagnosticLocation::createBegin( + AcquireNode->getStmtForDiagnostics(), C.getSourceManager(), + AcquireNode->getLocationContext()); + + R = std::make_unique<PathSensitiveBugReport>( + Type, Msg, ErrorNode, LocUsedForUniqueing, + AcquireNode->getLocationContext()->getDecl()); + } + } + if (!R) + R = std::make_unique<PathSensitiveBugReport>(Type, Msg, ErrorNode); if (Range) R->addRange(*Range); R->markInteresting(Sym); |

