diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp | 47 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 1 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp | 24 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 4 |
4 files changed, 39 insertions, 37 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp index 685fd88b165..b5e78b5d58d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MIGChecker.cpp @@ -80,43 +80,10 @@ public: checkReturnAux(RS, C); } - class Visitor : public BugReporterVisitor { - public: - void Profile(llvm::FoldingSetNodeID &ID) const { - static int X = 0; - ID.AddPointer(&X); - } - - std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N, - BugReporterContext &BRC, BugReport &R); - }; }; } // end anonymous namespace -// FIXME: It's a 'const ParmVarDecl *' but there's no ready-made GDM traits -// specialization for this sort of types. -REGISTER_TRAIT_WITH_PROGRAMSTATE(ReleasedParameter, const void *) - -std::shared_ptr<PathDiagnosticPiece> -MIGChecker::Visitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, - BugReport &R) { - const auto *NewPVD = static_cast<const ParmVarDecl *>( - N->getState()->get<ReleasedParameter>()); - const auto *OldPVD = static_cast<const ParmVarDecl *>( - N->getFirstPred()->getState()->get<ReleasedParameter>()); - if (OldPVD == NewPVD) - return nullptr; - - assert(NewPVD && "What is deallocated cannot be un-deallocated!"); - SmallString<64> Str; - llvm::raw_svector_ostream OS(Str); - OS << "Value passed through parameter '" << NewPVD->getName() - << "' is deallocated"; - - PathDiagnosticLocation Loc = - PathDiagnosticLocation::create(N->getLocation(), BRC.getSourceManager()); - return std::make_shared<PathDiagnosticEventPiece>(Loc, OS.str()); -} +REGISTER_TRAIT_WITH_PROGRAMSTATE(ReleasedParameter, bool) static const ParmVarDecl *getOriginParam(SVal V, CheckerContext &C) { SymbolRef Sym = V.getAsSymbol(); @@ -195,7 +162,16 @@ void MIGChecker::checkPostCall(const CallEvent &Call, CheckerContext &C) const { if (!PVD) return; - C.addTransition(C.getState()->set<ReleasedParameter>(PVD)); + const NoteTag *T = C.getNoteTag([this, PVD](BugReport &BR) -> std::string { + if (&BR.getBugType() != &BT) + return ""; + SmallString<64> Str; + llvm::raw_svector_ostream OS(Str); + OS << "Value passed through parameter '" << PVD->getName() + << "\' is deallocated"; + return OS.str(); + }); + C.addTransition(C.getState()->set<ReleasedParameter>(true), T); } // Returns true if V can potentially represent a "successful" kern_return_t. @@ -260,7 +236,6 @@ void MIGChecker::checkReturnAux(const ReturnStmt *RS, CheckerContext &C) const { R->addRange(RS->getSourceRange()); bugreporter::trackExpressionValue(N, RS->getRetValue(), *R, false); - R->addVisitor(llvm::make_unique<Visitor>()); C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 1a6314d48b2..b9b579b48bf 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2612,6 +2612,7 @@ std::pair<BugReport*, std::unique_ptr<VisitorsDiagnosticsTy>> findValidReport( R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>()); R->addVisitor(llvm::make_unique<ConditionBRVisitor>()); R->addVisitor(llvm::make_unique<CXXSelfAssignmentBRVisitor>()); + R->addVisitor(llvm::make_unique<TagVisitor>()); BugReporterContext BRC(Reporter, ErrorGraph.BackMap); diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index c86ae43ccd3..2aa5e264139 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -2492,6 +2492,30 @@ FalsePositiveRefutationBRVisitor::VisitNode(const ExplodedNode *N, return nullptr; } +int NoteTag::Kind = 0; + +void TagVisitor::Profile(llvm::FoldingSetNodeID &ID) const { + static int Tag = 0; + ID.AddPointer(&Tag); +} + +std::shared_ptr<PathDiagnosticPiece> +TagVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, + BugReport &R) { + ProgramPoint PP = N->getLocation(); + const NoteTag *T = dyn_cast_or_null<NoteTag>(PP.getTag()); + if (!T) + return nullptr; + + if (Optional<std::string> Msg = T->generateMessage(BRC, R)) { + PathDiagnosticLocation Loc = + PathDiagnosticLocation::create(PP, BRC.getSourceManager()); + return std::make_shared<PathDiagnosticEventPiece>(Loc, *Msg); + } + + return nullptr; +} + void FalsePositiveRefutationBRVisitor::Profile( llvm::FoldingSetNodeID &ID) const { static int Tag = 0; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index fb86ceab135..e36820fa2a4 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -201,7 +201,9 @@ ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()), BR(mgr, *this), - VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) { + VisitedCallees(VisitedCalleesIn), + HowToInline(HowToInlineIn), + NoteTags(G.getAllocator()) { unsigned TrimInterval = mgr.options.GraphTrimInterval; if (TrimInterval != 0) { // Enable eager node reclamation when constructing the ExplodedGraph. |