From 6a61922239de8018239eef23328dba457874064c Mon Sep 17 00:00:00 2001 From: Anton Yartsev Date: Mon, 17 Feb 2014 18:25:34 +0000 Subject: [PATCH] [analyzer] Improved checker naming in CFG dump. This implements FIXME from Checker.cpp (FIXME: We want to return the package + name of the checker here.) and replaces hardcoded checker names with the new ones obtained via getCheckName().getName(). llvm-svn: 201525 --- clang/include/clang/Analysis/ProgramPoint.h | 6 +++--- clang/include/clang/StaticAnalyzer/Core/Checker.h | 11 +++++++++++ clang/lib/Analysis/ProgramPoint.cpp | 7 ++++--- .../StaticAnalyzer/Checkers/CallAndMessageChecker.cpp | 2 +- .../Checkers/MacOSKeychainAPIChecker.cpp | 2 +- clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 15 +++++++++------ .../StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp | 2 +- .../lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp | 18 ++++++++---------- clang/lib/StaticAnalyzer/Core/Checker.cpp | 17 +++++++++++++++-- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 16 ++++++++++------ .../StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp | 2 +- 11 files changed, 64 insertions(+), 34 deletions(-) diff --git a/clang/include/clang/Analysis/ProgramPoint.h b/clang/include/clang/Analysis/ProgramPoint.h index 333329d8..314d53e 100644 --- a/clang/include/clang/Analysis/ProgramPoint.h +++ b/clang/include/clang/Analysis/ProgramPoint.h @@ -658,11 +658,11 @@ protected: private: const void *TagKind; }; - + class SimpleProgramPointTag : public ProgramPointTag { - std::string desc; + std::string Desc; public: - SimpleProgramPointTag(StringRef description); + SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg); StringRef getTagDescription() const; }; diff --git a/clang/include/clang/StaticAnalyzer/Core/Checker.h b/clang/include/clang/StaticAnalyzer/Core/Checker.h index 9b78bab..6153b87 100644 --- a/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -465,6 +465,17 @@ public: const char *NL, const char *Sep) const { } }; +/// Dump checker name to stream. +raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker); + +/// Tag that can use a checker name as a message provider +/// (see SimpleProgramPointTag). +class CheckerProgramPointTag : public SimpleProgramPointTag { +public: + CheckerProgramPointTag(StringRef CheckerName, StringRef Msg); + CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg); +}; + template ::iterator I = Errors.begin(), E = Errors.end(); I != E; ++I) { @@ -2251,11 +2251,17 @@ void MallocChecker::printState(raw_ostream &Out, ProgramStateRef State, RegionStateTy RS = State->get(); if (!RS.isEmpty()) { - Out << Sep << "MallocChecker:" << NL; + Out << Sep << "MallocChecker :" << NL; for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) { + const RefState *RefS = State->get(I.getKey()); + AllocationFamily Family = RefS->getAllocationFamily(); + Optional CheckKind = getCheckIfTracked(Family); + I.getKey()->dumpToStream(Out); Out << " : "; I.getData().dump(Out); + if (CheckKind.hasValue()) + Out << " (" << CheckNames[*CheckKind].getName() << ")"; Out << NL; } } @@ -2269,11 +2275,8 @@ void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) { mgr.getCurrentCheckName(); // We currently treat NewDeleteLeaks checker as a subchecker of NewDelete // checker. - if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) { + if (!checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker]) checker->ChecksEnabled[MallocChecker::CK_NewDeleteChecker] = true; - checker->CheckNames[MallocChecker::CK_NewDeleteChecker] = - mgr.getCurrentCheckName(); - } } #define REGISTER_CHECKER(name) \ diff --git a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp index 33200a0..273b221 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp @@ -350,7 +350,7 @@ void ObjCSelfInitChecker::printState(raw_ostream &Out, ProgramStateRef State, if (FlagMap.isEmpty() && !DidCallInit && !PreCallFlags) return; - Out << Sep << NL << "ObjCSelfInitChecker:" << NL; + Out << Sep << NL << *this << " :" << NL; if (DidCallInit) Out << " An init method has been called." << NL; diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 1661622..1cb92b8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -2344,7 +2344,7 @@ class RetainCountChecker mutable OwningPtr leakWithinFunction, leakAtReturn; mutable OwningPtr leakWithinFunctionGC, leakAtReturnGC; - typedef llvm::DenseMap SymbolTagMap; + typedef llvm::DenseMap SymbolTagMap; // This map is only used to ensure proper deletion of any allocated tags. mutable SymbolTagMap DeadSymbolTags; @@ -3258,8 +3258,7 @@ void RetainCountChecker::checkPreStmt(const ReturnStmt *S, return; // Update the autorelease counts. - static SimpleProgramPointTag - AutoreleaseTag("RetainCountChecker : Autorelease"); + static CheckerProgramPointTag AutoreleaseTag(this, "Autorelease"); state = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag, C, Sym, X); // Did we cache out? @@ -3320,8 +3319,7 @@ void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S, // Generate an error node. state = setRefBinding(state, Sym, X); - static SimpleProgramPointTag - ReturnOwnLeakTag("RetainCountChecker : ReturnsOwnLeak"); + static CheckerProgramPointTag ReturnOwnLeakTag(this, "ReturnsOwnLeak"); ExplodedNode *N = C.addTransition(state, Pred, &ReturnOwnLeakTag); if (N) { const LangOptions &LOpts = C.getASTContext().getLangOpts(); @@ -3341,8 +3339,8 @@ void RetainCountChecker::checkReturnWithRetEffect(const ReturnStmt *S, // owned object. state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned); - static SimpleProgramPointTag - ReturnNotOwnedTag("RetainCountChecker : ReturnNotOwnedForOwned"); + static CheckerProgramPointTag ReturnNotOwnedTag(this, + "ReturnNotOwnedForOwned"); ExplodedNode *N = C.addTransition(state, Pred, &ReturnNotOwnedTag); if (N) { if (!returnNotOwnedForOwned) @@ -3628,13 +3626,13 @@ void RetainCountChecker::checkEndFunction(CheckerContext &Ctx) const { const ProgramPointTag * RetainCountChecker::getDeadSymbolTag(SymbolRef sym) const { - const SimpleProgramPointTag *&tag = DeadSymbolTags[sym]; + const CheckerProgramPointTag *&tag = DeadSymbolTags[sym]; if (!tag) { SmallString<64> buf; llvm::raw_svector_ostream out(buf); - out << "RetainCountChecker : Dead Symbol : "; + out << "Dead Symbol : "; sym->dumpToStream(out); - tag = new SimpleProgramPointTag(out.str()); + tag = new CheckerProgramPointTag(this, out.str()); } return tag; } diff --git a/clang/lib/StaticAnalyzer/Core/Checker.cpp b/clang/lib/StaticAnalyzer/Core/Checker.cpp index e2b2a19..1a3965a 100644 --- a/clang/lib/StaticAnalyzer/Core/Checker.cpp +++ b/clang/lib/StaticAnalyzer/Core/Checker.cpp @@ -18,12 +18,25 @@ using namespace clang; using namespace ento; StringRef CheckerBase::getTagDescription() const { - // FIXME: We want to return the package + name of the checker here. - return "A Checker"; + return getCheckName().getName(); } CheckName CheckerBase::getCheckName() const { return Name; } +CheckerProgramPointTag::CheckerProgramPointTag(StringRef CheckerName, + StringRef Msg) + : SimpleProgramPointTag(CheckerName, Msg) {} + +CheckerProgramPointTag::CheckerProgramPointTag(const CheckerBase *Checker, + StringRef Msg) + : SimpleProgramPointTag(Checker->getCheckName().getName(), Msg) {} + +raw_ostream& clang::ento::operator<<(raw_ostream &Out, + const CheckerBase &Checker) { + Out << Checker.getCheckName().getName(); + return Out; +} + void Checker= AMgr.options.maxBlockVisitOnPath) { - static SimpleProgramPointTag tag("ExprEngine : Block count exceeded"); + static SimpleProgramPointTag tag(TagProviderName, "Block count exceeded"); const ExplodedNode *Sink = nodeBuilder.generateSink(Pred->getState(), Pred, &tag); @@ -2067,7 +2069,7 @@ void ExprEngine::evalLoad(ExplodedNodeSet &Dst, QualType ValTy = TR->getValueType(); if (const ReferenceType *RT = ValTy->getAs()) { static SimpleProgramPointTag - loadReferenceTag("ExprEngine : Load Reference"); + loadReferenceTag(TagProviderName, "Load Reference"); ExplodedNodeSet Tmp; evalLoadCommon(Tmp, NodeEx, BoundEx, Pred, state, location, &loadReferenceTag, @@ -2150,7 +2152,7 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst, // instead "int *p" is noted as // "Variable 'p' initialized to a null pointer value" - static SimpleProgramPointTag tag("ExprEngine: Location"); + static SimpleProgramPointTag tag(TagProviderName, "Location"); Bldr.generateNode(NodeEx, Pred, state, &tag); } ExplodedNodeSet Tmp; @@ -2162,8 +2164,10 @@ void ExprEngine::evalLocation(ExplodedNodeSet &Dst, std::pair ExprEngine::geteagerlyAssumeBinOpBifurcationTags() { static SimpleProgramPointTag - eagerlyAssumeBinOpBifurcationTrue("ExprEngine : Eagerly Assume True"), - eagerlyAssumeBinOpBifurcationFalse("ExprEngine : Eagerly Assume False"); + eagerlyAssumeBinOpBifurcationTrue(TagProviderName, + "Eagerly Assume True"), + eagerlyAssumeBinOpBifurcationFalse(TagProviderName, + "Eagerly Assume False"); return std::make_pair(&eagerlyAssumeBinOpBifurcationTrue, &eagerlyAssumeBinOpBifurcationFalse); } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index e5b46ca..04fa11a 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -282,7 +282,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { // they occurred. ExplodedNodeSet CleanedNodes; if (LastSt && Blk && AMgr.options.AnalysisPurgeOpt != PurgeNone) { - static SimpleProgramPointTag retValBind("ExprEngine : Bind Return Value"); + static SimpleProgramPointTag retValBind("ExprEngine", "Bind Return Value"); PostStmt Loc(LastSt, calleeCtx, &retValBind); bool isNew; ExplodedNode *BindedRetNode = G.getNode(Loc, state, false, &isNew); -- 2.7.4