From ca804539d908d3a0e8c72a0df5f1f571d29490bb Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 12 Aug 2011 23:04:46 +0000 Subject: [analyzer] change "tag" in ProgramPoint from "void*" to a ProgramPointTag*. Having a notion of an actual ProgramPointTag will aid in introspection of the analyzer's behavior. For example, the GraphViz output of the analyzer will pretty-print the tags in a useful manner. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137529 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/CFRefCount.cpp | 42 +++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'lib/StaticAnalyzer/Core/CFRefCount.cpp') diff --git a/lib/StaticAnalyzer/Core/CFRefCount.cpp b/lib/StaticAnalyzer/Core/CFRefCount.cpp index ad809e7649..46aacd473f 100644 --- a/lib/StaticAnalyzer/Core/CFRefCount.cpp +++ b/lib/StaticAnalyzer/Core/CFRefCount.cpp @@ -88,11 +88,11 @@ namespace { class GenericNodeBuilderRefCount { StmtNodeBuilder *SNB; const Stmt *S; - const void *tag; + const ProgramPointTag *tag; EndOfFunctionNodeBuilder *ENB; public: GenericNodeBuilderRefCount(StmtNodeBuilder &snb, const Stmt *s, - const void *t) + const ProgramPointTag *t) : SNB(&snb), S(s), tag(t), ENB(0) {} GenericNodeBuilderRefCount(EndOfFunctionNodeBuilder &enb) @@ -1671,9 +1671,11 @@ public: BugType *overAutorelease; BugType *returnNotOwnedForOwned; BugReporter *BR; + + llvm::DenseMap DeadSymbolTags; - const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, ArgEffect E, - RefVal::Kind& hasErr); + const GRState * Update(const GRState * state, SymbolRef sym, RefVal V, + ArgEffect E, RefVal::Kind& hasErr); void ProcessNonLeakError(ExplodedNodeSet& Dst, StmtNodeBuilder& Builder, @@ -1699,7 +1701,11 @@ public: leakWithinFunction(0), leakAtReturn(0), overAutorelease(0), returnNotOwnedForOwned(0), BR(0) {} - virtual ~CFRefCount() {} + virtual ~CFRefCount() { + for (llvm::DenseMap::iterator + it = DeadSymbolTags.begin(), ei = DeadSymbolTags.end(); it != ei; ++it) + delete it->second; + } void RegisterChecks(ExprEngine &Eng); @@ -1757,6 +1763,8 @@ public: const GRState* state, SymbolReaper& SymReaper); + const ProgramPointTag *getDeadSymbolTag(SymbolRef sym); + std::pair HandleAutoreleaseCounts(const GRState * state, GenericNodeBuilderRefCount Bd, ExplodedNode* Pred, ExprEngine &Eng, @@ -2968,7 +2976,7 @@ void CFRefCount::evalReturn(ExplodedNodeSet& Dst, return; // Update the autorelease counts. - static unsigned autoreleasetag = 0; + static SimpleProgramPointTag autoreleasetag("CFRefCount : Autorelease"); GenericNodeBuilderRefCount Bd(Builder, S, &autoreleasetag); bool stop = false; llvm::tie(Pred, state) = HandleAutoreleaseCounts(state , Bd, Pred, Eng, Sym, @@ -3031,7 +3039,8 @@ void CFRefCount::evalReturnWithRetEffect(ExplodedNodeSet &Dst, if (hasError) { // Generate an error node. - static int ReturnOwnLeakTag = 0; + static SimpleProgramPointTag + ReturnOwnLeakTag("CFRefCount : ReturnsOwnLeak"); state = state->set(Sym, X); ExplodedNode *N = Builder.generateNode(PostStmt(S, Pred->getLocationContext(), @@ -3051,8 +3060,8 @@ void CFRefCount::evalReturnWithRetEffect(ExplodedNodeSet &Dst, if (RE.isOwned()) { // Trying to return a not owned object to a caller expecting an // owned object. - - static int ReturnNotOwnedForOwnedTag = 0; + static SimpleProgramPointTag + ReturnNotOwnedForOwnedTag("CFRefCount : ReturnNotOwnedForOwned"); state = state->set(Sym, X ^ RefVal::ErrorReturnedNotOwned); if (ExplodedNode *N = Builder.generateNode(PostStmt(S, Pred->getLocationContext(), @@ -3375,6 +3384,17 @@ void CFRefCount::evalEndPath(ExprEngine& Eng, ProcessLeaks(state, Leaked, Bd, Eng, Pred); } +const ProgramPointTag *CFRefCount::getDeadSymbolTag(SymbolRef sym) { + const SimpleProgramPointTag *&tag = DeadSymbolTags[sym]; + if (!tag) { + llvm::SmallString<128> buf; + llvm::raw_svector_ostream out(buf); + out << "CFRefCount : Dead Symbol : " << sym->getSymbolID(); + tag = new SimpleProgramPointTag(out.str()); + } + return tag; +} + void CFRefCount::evalDeadSymbols(ExplodedNodeSet& Dst, ExprEngine& Eng, StmtNodeBuilder& Builder, @@ -3391,7 +3411,7 @@ void CFRefCount::evalDeadSymbols(ExplodedNodeSet& Dst, if (const RefVal* T = B.lookup(Sym)){ // Use the symbol as the tag. // FIXME: This might not be as unique as we would like. - GenericNodeBuilderRefCount Bd(Builder, S, Sym); + GenericNodeBuilderRefCount Bd(Builder, S, getDeadSymbolTag(Sym)); bool stop = false; llvm::tie(Pred, state) = HandleAutoreleaseCounts(state, Bd, Pred, Eng, Sym, *T, stop); @@ -3409,7 +3429,7 @@ void CFRefCount::evalDeadSymbols(ExplodedNodeSet& Dst, state = HandleSymbolDeath(state, *I, *T, Leaked); } - static unsigned LeakPPTag = 0; + static SimpleProgramPointTag LeakPPTag("CFRefCount : Leak"); { GenericNodeBuilderRefCount Bd(Builder, S, &LeakPPTag); Pred = ProcessLeaks(state, Leaked, Bd, Eng, Pred); -- cgit v1.2.3-18-g5258