forked from OSchip/llvm-project
[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
This commit is contained in:
parent
06bd44b3e8
commit
6a61922239
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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 <typename CHECK1, typename CHECK2=check::_VoidCheck,
|
||||
typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck,
|
||||
typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck,
|
||||
|
|
|
@ -43,9 +43,10 @@ ProgramPoint ProgramPoint::getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
|
|||
}
|
||||
}
|
||||
|
||||
SimpleProgramPointTag::SimpleProgramPointTag(StringRef description)
|
||||
: desc(description) {}
|
||||
SimpleProgramPointTag::SimpleProgramPointTag(StringRef MsgProvider,
|
||||
StringRef Msg)
|
||||
: Desc((MsgProvider + " : " + Msg).str()) {}
|
||||
|
||||
StringRef SimpleProgramPointTag::getTagDescription() const {
|
||||
return desc;
|
||||
return Desc;
|
||||
}
|
||||
|
|
|
@ -455,7 +455,7 @@ void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
|
|||
ProgramStateRef state,
|
||||
const ObjCMethodCall &Msg) const {
|
||||
ASTContext &Ctx = C.getASTContext();
|
||||
static SimpleProgramPointTag Tag("CallAndMessageChecker : NilReceiver");
|
||||
static CheckerProgramPointTag Tag(this, "NilReceiver");
|
||||
|
||||
// Check the return type of the message expression. A message to nil will
|
||||
// return different values depending on the return type and the architecture.
|
||||
|
|
|
@ -575,7 +575,7 @@ void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
|
|||
return;
|
||||
}
|
||||
|
||||
static SimpleProgramPointTag Tag("MacOSKeychainAPIChecker : DeadSymbolsLeak");
|
||||
static CheckerProgramPointTag Tag(this, "DeadSymbolsLeak");
|
||||
ExplodedNode *N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
|
||||
|
||||
// Generate the error reports.
|
||||
|
|
|
@ -1738,7 +1738,7 @@ void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
|
|||
// Generate leak node.
|
||||
ExplodedNode *N = C.getPredecessor();
|
||||
if (!Errors.empty()) {
|
||||
static SimpleProgramPointTag Tag("MallocChecker : DeadSymbolsLeak");
|
||||
static CheckerProgramPointTag Tag("MallocChecker", "DeadSymbolsLeak");
|
||||
N = C.addTransition(C.getState(), C.getPredecessor(), &Tag);
|
||||
for (SmallVectorImpl<SymbolRef>::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<RegionState>();
|
||||
|
||||
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<RegionState>(I.getKey());
|
||||
AllocationFamily Family = RefS->getAllocationFamily();
|
||||
Optional<MallocChecker::CheckKind> 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) \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -2344,7 +2344,7 @@ class RetainCountChecker
|
|||
mutable OwningPtr<CFRefBug> leakWithinFunction, leakAtReturn;
|
||||
mutable OwningPtr<CFRefBug> leakWithinFunctionGC, leakAtReturnGC;
|
||||
|
||||
typedef llvm::DenseMap<SymbolRef, const SimpleProgramPointTag *> SymbolTagMap;
|
||||
typedef llvm::DenseMap<SymbolRef, const CheckerProgramPointTag *> 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;
|
||||
}
|
||||
|
|
|
@ -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<check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
|
||||
check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
|
||||
check::_VoidCheck, check::_VoidCheck, check::_VoidCheck,
|
||||
|
|
|
@ -55,6 +55,8 @@ STATISTIC(NumTimesRetriedWithoutInlining,
|
|||
// Engine construction and deletion.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static const char* TagProviderName = "ExprEngine";
|
||||
|
||||
ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
|
||||
SetOfConstDecls *VisitedCalleesIn,
|
||||
FunctionSummariesTy *FS,
|
||||
|
@ -366,7 +368,7 @@ void ExprEngine::removeDead(ExplodedNode *Pred, ExplodedNodeSet &Out,
|
|||
|
||||
// Process any special transfer function for dead symbols.
|
||||
// A tag to track convenience transitions, which can be removed at cleanup.
|
||||
static SimpleProgramPointTag cleanupTag("ExprEngine : Clean Node");
|
||||
static SimpleProgramPointTag cleanupTag(TagProviderName, "Clean Node");
|
||||
if (!SymReaper.hasDeadSymbols()) {
|
||||
// Generate a CleanedNode that has the environment and store cleaned
|
||||
// up. Since no symbols are dead, we can optimize and not clean out
|
||||
|
@ -1273,7 +1275,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
|
|||
|
||||
// FIXME: Refactor this into a checker.
|
||||
if (nodeBuilder.getContext().blockCount() >= 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<ReferenceType>()) {
|
||||
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<const ProgramPointTag *, const ProgramPointTag*>
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue