From 3148eb4a75f70f2636075c364d03104223f004d3 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 24 Jan 2009 00:55:43 +0000 Subject: [PATCH] More hacking on static analyzer diagnostics. When emitting summary diagnostics the code paths for diagnostics involving paths or single locations are now unified. This patch also constifies many arguments/methods that are touched by this logic, leading to a nice overall code cleanup. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62903 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Analysis/PathSensitive/BugReporter.h | 14 +- .../Analysis/PathSensitive/ExplodedGraph.h | 17 +- lib/Analysis/BugReporter.cpp | 184 ++++++++---------- lib/Analysis/CFRefCount.cpp | 48 +++-- lib/Analysis/ExplodedGraph.cpp | 25 ++- test/Analysis/NSString.m | 2 +- test/Analysis/retain-release.m | 4 +- 7 files changed, 130 insertions(+), 164 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index ba6f253963..bcc28bdc5c 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -70,16 +70,16 @@ public: class BugReport { BugType& Desc; - ExplodedNode *EndNode; + const ExplodedNode *EndNode; SourceRange R; public: - BugReport(BugType& D, ExplodedNode *n) : Desc(D), EndNode(n) {} + BugReport(BugType& D, const ExplodedNode *n) : Desc(D), EndNode(n) {} virtual ~BugReport(); const BugType& getBugType() const { return Desc; } BugType& getBugType() { return Desc; } - ExplodedNode* getEndNode() const { return EndNode; } + const ExplodedNode* getEndNode() const { return EndNode; } Stmt* getStmt(BugReporter& BR) const; @@ -98,16 +98,16 @@ public: } virtual PathDiagnosticPiece* getEndPath(BugReporter& BR, - ExplodedNode* N); + const ExplodedNode* N); virtual FullSourceLoc getLocation(SourceManager& Mgr); virtual void getRanges(BugReporter& BR,const SourceRange*& beg, const SourceRange*& end); - virtual PathDiagnosticPiece* VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, + virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, BugReporter& BR); }; diff --git a/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/include/clang/Analysis/PathSensitive/ExplodedGraph.h index 3406d178dd..954b096b8e 100644 --- a/include/clang/Analysis/PathSensitive/ExplodedGraph.h +++ b/include/clang/Analysis/PathSensitive/ExplodedGraph.h @@ -179,9 +179,9 @@ public: // Iterators over successor and predecessor vertices. typedef ExplodedNode** succ_iterator; - typedef const ExplodedNode** const_succ_iterator; + typedef const ExplodedNode* const * const_succ_iterator; typedef ExplodedNode** pred_iterator; - typedef const ExplodedNode** const_pred_iterator; + typedef const ExplodedNode* const * const_pred_iterator; pred_iterator pred_begin() { return (ExplodedNode**) Preds.begin(); } pred_iterator pred_end() { return (ExplodedNode**) Preds.end(); } @@ -289,8 +289,8 @@ public: return llvm::dyn_cast(&CodeDecl); } - ExplodedGraphImpl* Trim(ExplodedNodeImpl** NBeg, - ExplodedNodeImpl** NEnd) const; + ExplodedGraphImpl* Trim(const ExplodedNodeImpl* const * NBeg, + const ExplodedNodeImpl* const * NEnd) const; }; @@ -411,15 +411,18 @@ public: // Utility. - ExplodedGraph* Trim(NodeTy** NBeg, NodeTy** NEnd) const { + ExplodedGraph* + Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd) const { if (NBeg == NEnd) return NULL; assert (NBeg < NEnd); - ExplodedNodeImpl** NBegImpl = (ExplodedNodeImpl**) NBeg; - ExplodedNodeImpl** NEndImpl = (ExplodedNodeImpl**) NEnd; + const ExplodedNodeImpl* const* NBegImpl = + (const ExplodedNodeImpl* const*) NBeg; + const ExplodedNodeImpl* const* NEndImpl = + (const ExplodedNodeImpl* const*) NEnd; return static_cast(ExplodedGraphImpl::Trim(NBegImpl, NEndImpl)); diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 9d4d059341..b08f5cb793 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -64,27 +64,30 @@ static inline Stmt* GetStmt(const CFGBlock* B) { return (*B)[0]; } -static inline ExplodedNode* -GetNextNode(ExplodedNode* N) { +static inline const ExplodedNode* +GetNextNode(const ExplodedNode* N) { return N->pred_empty() ? NULL : *(N->pred_begin()); } -static Stmt* GetLastStmt(ExplodedNode* N) { +static Stmt* GetLastStmt(const ExplodedNode* N) { assert (isa(N->getLocation())); for (N = GetNextNode(N); N; N = GetNextNode(N)) { - ProgramPoint P = N->getLocation(); - - if (PostStmt* PS = dyn_cast(&P)) - return PS->getStmt(); + if (PostStmt* PS = dyn_cast(&P)) return PS->getStmt(); } return NULL; } +static inline Stmt* GetStmt(const ExplodedNode* N) { + ProgramPoint ProgP = N->getLocation(); + return isa(ProgP) ? GetLastStmt(N) : GetStmt(ProgP); +} + + static void ExecutionContinues(std::ostringstream& os, SourceManager& SMgr, - Stmt* S) { + const Stmt* S) { if (!S) return; @@ -100,7 +103,7 @@ static void ExecutionContinues(std::ostringstream& os, SourceManager& SMgr, static inline void ExecutionContinues(std::ostringstream& os, SourceManager& SMgr, - ExplodedNode* N) { + const ExplodedNode* N) { ExecutionContinues(os, SMgr, GetStmt(N->getLocation())); } @@ -129,7 +132,7 @@ Stmt* BugReport::getStmt(BugReporter& BR) const { PathDiagnosticPiece* BugReport::getEndPath(BugReporter& BR, - ExplodedNode* EndPathNode) { + const ExplodedNode* EndPathNode) { Stmt* S = getStmt(BR); @@ -165,7 +168,7 @@ FullSourceLoc BugReport::getLocation(SourceManager& Mgr) { if (!EndNode) return FullSourceLoc(); - Stmt* S = GetStmt(EndNode->getLocation()); + Stmt* S = GetStmt(EndNode); if (!S) return FullSourceLoc(); @@ -173,21 +176,22 @@ FullSourceLoc BugReport::getLocation(SourceManager& Mgr) { return FullSourceLoc(S->getLocStart(), Mgr); } -PathDiagnosticPiece* BugReport::VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, +PathDiagnosticPiece* BugReport::VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, BugReporter& BR) { return NULL; } static std::pair*, ExplodedNode*> -MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { +MakeReportGraph(const ExplodedGraph* G, + const ExplodedNode* N) { - llvm::OwningPtr > GTrim(G->Trim(&N, &N+1)); + llvm::OwningPtr< ExplodedGraph > GTrim(G->Trim(&N, &N+1)); // Find the error node in the trimmed graph. - ExplodedNode* NOld = N; + const ExplodedNode* NOld = N; N = 0; for (ExplodedGraph::node_iterator @@ -203,21 +207,21 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { assert(N); // Create a new graph with a single path. - - G = new ExplodedGraph(GTrim->getCFG(), GTrim->getCodeDecl(), - GTrim->getContext()); + ExplodedGraph *GNew = + new ExplodedGraph(GTrim->getCFG(), GTrim->getCodeDecl(), + GTrim->getContext()); // Sometimes TrimGraph can contain a cycle. Perform a reverse DFS // to the root node, and then construct a new graph that contains only // a single path. - llvm::DenseMap Visited; - llvm::SmallVector*, 10> WS; + llvm::DenseMap Visited; + llvm::SmallVector*, 10> WS; WS.push_back(N); unsigned cnt = 0; - ExplodedNode* Root = 0; + const ExplodedNode* Root = 0; while (!WS.empty()) { - ExplodedNode* Node = WS.back(); + const ExplodedNode* Node = WS.back(); WS.pop_back(); if (Visited.find(Node) != Visited.end()) @@ -230,7 +234,7 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { break; } - for (ExplodedNode::pred_iterator I=Node->pred_begin(), + for (ExplodedNode::const_pred_iterator I=Node->pred_begin(), E=Node->pred_end(); I!=E; ++I) WS.push_back(*I); } @@ -242,15 +246,14 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { ExplodedNode *Last = 0, *First = 0; for ( N = Root ;;) { - // Lookup the number associated with the current node. - llvm::DenseMap::iterator I=Visited.find(N); + llvm::DenseMap::iterator I = Visited.find(N); assert (I != Visited.end()); // Create the equivalent node in the new graph with the same state // and location. ExplodedNode* NewN = - G->getNode(N->getLocation(), N->getState()); + GNew->getNode(N->getLocation(), N->getState()); // Link up the new node with the previous node. if (Last) @@ -266,8 +269,8 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { // Find the next successor node. We choose the node that is marked // with the lowest DFS number. - ExplodedNode::succ_iterator SI = N->succ_begin(); - ExplodedNode::succ_iterator SE = N->succ_end(); + ExplodedNode::const_succ_iterator SI = N->succ_begin(); + ExplodedNode::const_succ_iterator SE = N->succ_end(); N = 0; for (unsigned MinVal = 0; SI != SE; ++SI) { @@ -287,12 +290,12 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { } assert (First); - return std::make_pair(G, First); + return std::make_pair(GNew, First); } -static VarDecl* GetMostRecentVarDeclBinding(ExplodedNode* N, - GRStateManager& VMgr, - SVal X) { +static const VarDecl* +GetMostRecentVarDeclBinding(const ExplodedNode* N, + GRStateManager& VMgr, SVal X) { for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) { @@ -328,16 +331,16 @@ class VISIBILITY_HIDDEN NotableSymbolHandler SymbolRef Sym; const GRState* PrevSt; - Stmt* S; + const Stmt* S; GRStateManager& VMgr; - ExplodedNode* Pred; + const ExplodedNode* Pred; PathDiagnostic& PD; BugReporter& BR; public: - NotableSymbolHandler(SymbolRef sym, const GRState* prevst, Stmt* s, - GRStateManager& vmgr, ExplodedNode* pred, + NotableSymbolHandler(SymbolRef sym, const GRState* prevst, const Stmt* s, + GRStateManager& vmgr, const ExplodedNode* pred, PathDiagnostic& pd, BugReporter& br) : Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {} @@ -367,7 +370,7 @@ public: VarDecl *VD = 0; - if (BinaryOperator* B = dyn_cast(S)) { + if (const BinaryOperator* B = dyn_cast(S)) { if (!B->isAssignmentOp()) return true; @@ -379,7 +382,7 @@ public: VD = dyn_cast(DR->getDecl()); } - else if (DeclStmt* DS = dyn_cast(S)) { + else if (const DeclStmt* DS = dyn_cast(S)) { // FIXME: Eventually CFGs won't have DeclStmts. Right now we // assume that each DeclStmt has a single Decl. This invariant // holds by contruction in the CFG. @@ -390,7 +393,7 @@ public: return true; // What is the most recently referenced variable with this binding? - VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V); + const VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V); if (!MostRecent) return true; @@ -411,11 +414,12 @@ public: }; } -static void HandleNotableSymbol(ExplodedNode* N, Stmt* S, +static void HandleNotableSymbol(const ExplodedNode* N, + const Stmt* S, SymbolRef Sym, BugReporter& BR, PathDiagnostic& PD) { - ExplodedNode* Pred = N->pred_empty() ? 0 : *N->pred_begin(); + const ExplodedNode* Pred = N->pred_empty() ? 0 : *N->pred_begin(); const GRState* PrevSt = Pred ? Pred->getState() : 0; if (!PrevSt) @@ -433,13 +437,13 @@ class VISIBILITY_HIDDEN ScanNotableSymbols : public StoreManager::BindingsHandler { llvm::SmallSet AlreadyProcessed; - ExplodedNode* N; + const ExplodedNode* N; Stmt* S; GRBugReporter& BR; PathDiagnostic& PD; public: - ScanNotableSymbols(ExplodedNode* n, Stmt* s, GRBugReporter& br, + ScanNotableSymbols(const ExplodedNode* n, Stmt* s, GRBugReporter& br, PathDiagnostic& pd) : N(n), S(s), BR(br), PD(pd) {} @@ -472,14 +476,14 @@ public: void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R) { - ExplodedNode* N = R.getEndNode(); + const ExplodedNode* N = R.getEndNode(); if (!N) return; // Construct a new graph that contains only a single path from the error // node to a root. - const std::pair*,ExplodedNode*> + const std::pair*, ExplodedNode*> GPair = MakeReportGraph(&getGraph(), N); llvm::OwningPtr > ReportGraph(GPair.first); @@ -493,15 +497,15 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, else return; - ExplodedNode* NextNode = N->pred_empty() - ? NULL : *(N->pred_begin()); + const ExplodedNode* NextNode = N->pred_empty() + ? NULL : *(N->pred_begin()); ASTContext& Ctx = getContext(); SourceManager& SMgr = Ctx.getSourceManager(); while (NextNode) { - ExplodedNode* LastNode = N; + const ExplodedNode* LastNode = N; N = NextNode; NextNode = GetNextNode(N); @@ -697,7 +701,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, bool BugTypeCacheLocation::isCached(BugReport& R) { - ExplodedNode* N = R.getEndNode(); + const ExplodedNode* N = R.getEndNode(); if (!N) return false; @@ -727,73 +731,37 @@ void BugReporter::EmitWarning(BugReport& R) { GeneratePathDiagnostic(*D.get(), R); // Get the meta data. - std::pair Meta = R.getExtraDescriptiveText(); - - for (const char** s = Meta.first; s != Meta.second; ++s) - D->addMeta(*s); + for (const char** s = Meta.first; s != Meta.second; ++s) D->addMeta(*s); - // Emit a full diagnostic for the path if we have a PathDiagnosticClient. - + // Emit a summary diagnostic to the regular Diagnostics engine. PathDiagnosticClient* PD = getPathDiagnosticClient(); - - if (PD && !D->empty()) { - PD->HandlePathDiagnostic(D.take()); - // Output a diagnostic summarizing the report. - Diagnostic& Diag = getDiagnostic(); - Diag.Report(R.getLocation(getSourceManager()), - Diag.getCustomDiagID(Diagnostic::Warning,R.getDescription())); - return; - } - - // This isn't a bug with a path, but we can still emit a single - // line diagnostic. Determine the location. - FullSourceLoc L = D->empty() ? R.getLocation(getSourceManager()) - : D->back()->getLocation(); - - // Determine the range. - const SourceRange *Beg, *End; - - if (!D->empty()) { - Beg = D->back()->ranges_begin(); - End = D->back()->ranges_end(); - } - else - R.getRanges(*this, Beg, End); - - if (PD) { - PathDiagnosticPiece* piece = new PathDiagnosticPiece(L, R.getDescription()); - - for ( ; Beg != End; ++Beg) - piece->addRange(*Beg); - - D->push_back(piece); - PD->HandlePathDiagnostic(D.take()); - - // Output a diagnostic summarizing the report. - Diagnostic& Diag = getDiagnostic(); - Diag.Report(L,Diag.getCustomDiagID(Diagnostic::Warning,R.getDescription())); - return; - } - else { - std::string str; - - if (D->empty()) - str = R.getDescription(); - else - str = D->back()->getString(); - - Diagnostic& Diag = getDiagnostic(); - unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, str.c_str()); + const SourceRange *Beg = 0, *End = 0; + R.getRanges(*this, Beg, End); + Diagnostic& Diag = getDiagnostic(); + FullSourceLoc L = R.getLocation(getSourceManager()); + const char *msg = PD ? R.getBugType().getName() : R.getDescription(); + unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, msg); - switch (End-Beg) { + switch (End-Beg) { default: assert(0 && "Don't handle this many ranges yet!"); case 0: Diag.Report(L, ErrorDiag); break; case 1: Diag.Report(L, ErrorDiag) << Beg[0]; break; case 2: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1]; break; case 3: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1] << Beg[2]; break; - } } + + // Emit a full diagnostic for the path if we have a PathDiagnosticClient. + if (!PD) + return; + + if (D->empty()) { + PathDiagnosticPiece* piece = new PathDiagnosticPiece(L, R.getDescription()); + for ( ; Beg != End; ++Beg) piece->addRange(*Beg); + D->push_back(piece); + } + + PD->HandlePathDiagnostic(D.take()); } void BugReporter::EmitBasicReport(const char* name, const char* str, diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index 4731921731..bfc9d9058b 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -2215,11 +2215,7 @@ namespace { return "[naming convention] leak of returned object"; } } - - virtual const char* getDescription() const { - return "Object leaked"; - } - + virtual void EmitWarnings(BugReporter& BR); virtual void GetErrorNodes(std::vector*>& Nodes); virtual bool isLeak() const { return true; } @@ -2256,15 +2252,15 @@ namespace { SymbolRef getSymbol() const { return Sym; } - virtual PathDiagnosticPiece* getEndPath(BugReporter& BR, - ExplodedNode* N); + PathDiagnosticPiece* getEndPath(BugReporter& BR, + const ExplodedNode* N); - virtual std::pair getExtraDescriptiveText(); + std::pair getExtraDescriptiveText(); - virtual PathDiagnosticPiece* VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, - BugReporter& BR); + PathDiagnosticPiece* VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, + BugReporter& BR); }; @@ -2313,9 +2309,9 @@ std::pair CFRefReport::getExtraDescriptiveText() { } } -PathDiagnosticPiece* CFRefReport::VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, +PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, BugReporter& BR) { // Check if the type state has changed. @@ -2486,14 +2482,14 @@ class VISIBILITY_HIDDEN FindUniqueBinding : }; } -static std::pair*,MemRegion*> -GetAllocationSite(GRStateManager* StateMgr, ExplodedNode* N, +static std::pair*,const MemRegion*> +GetAllocationSite(GRStateManager* StateMgr, const ExplodedNode* N, SymbolRef Sym) { // Find both first node that referred to the tracked symbol and the // memory location that value was store to. - ExplodedNode* Last = N; - MemRegion* FirstBinding = 0; + const ExplodedNode* Last = N; + const MemRegion* FirstBinding = 0; while (N) { const GRState* St = N->getState(); @@ -2515,8 +2511,8 @@ GetAllocationSite(GRStateManager* StateMgr, ExplodedNode* N, return std::make_pair(Last, FirstBinding); } -PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& br, - ExplodedNode* EndN) { +PathDiagnosticPiece* +CFRefReport::getEndPath(BugReporter& br, const ExplodedNode* EndN) { GRBugReporter& BR = cast(br); @@ -2530,8 +2526,8 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& br, // We are a leak. Walk up the graph to get to the first node where the // symbol appeared, and also get the first VarDecl that tracked object // is stored to. - ExplodedNode* AllocNode = 0; - MemRegion* FirstBinding = 0; + const ExplodedNode* AllocNode = 0; + const MemRegion* FirstBinding = 0; llvm::tie(AllocNode, FirstBinding) = GetAllocationSite(&BR.getStateManager(), EndN, Sym); @@ -2566,7 +2562,7 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& br, PathDiagnosticPiece::DisplayHint Hint = PathDiagnosticPiece::Above; assert (!EndN->pred_empty()); // Not possible to have 0 predecessors. - ExplodedNode *Pred = *(EndN->pred_begin()); + const ExplodedNode *Pred = *(EndN->pred_begin()); ProgramPoint PredPos = Pred->getLocation(); if (PostStmt* PredPS = dyn_cast(&PredPos)) { @@ -2664,8 +2660,8 @@ bool Leak::isCached(BugReport& R) { SymbolRef Sym = static_cast(R).getSymbol(); - ExplodedNode* AllocNode = - GetAllocationSite(0, R.getEndNode(), Sym).first; + const ExplodedNode* AllocNode = + GetAllocationSite(0, R.getEndNode(), Sym).first; if (!AllocNode) return false; diff --git a/lib/Analysis/ExplodedGraph.cpp b/lib/Analysis/ExplodedGraph.cpp index 945416b1b5..4e41b60da3 100644 --- a/lib/Analysis/ExplodedGraph.cpp +++ b/lib/Analysis/ExplodedGraph.cpp @@ -120,36 +120,35 @@ ExplodedNodeImpl::NodeGroup::~NodeGroup() { if (getKind() == SizeOther) delete &getVector(getPtr()); } -ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources, - ExplodedNodeImpl** EndSources) const{ +ExplodedGraphImpl* +ExplodedGraphImpl::Trim(const ExplodedNodeImpl* const* BeginSources, + const ExplodedNodeImpl* const* EndSources) const{ - typedef llvm::DenseMap Pass1Ty; - typedef llvm::DenseMap Pass2Ty; + typedef llvm::DenseMap Pass1Ty; + typedef llvm::DenseMap Pass2Ty; Pass1Ty Pass1; Pass2Ty Pass2; - llvm::SmallVector WL2; + llvm::SmallVector WL2; { // ===- Pass 1 (reverse BFS) -=== // Enqueue the source nodes to the first worklist. - std::list > WL1; - std::list > WL1_Loops; + std::list > WL1, WL1_Loops; - for (ExplodedNodeImpl** I = BeginSources; I != EndSources; ++I) + for (const ExplodedNodeImpl* const* I = BeginSources; I != EndSources; ++I) WL1.push_back(std::make_pair(*I, *I)); // Process the worklist. while (! (WL1.empty() && WL1_Loops.empty())) { - - ExplodedNodeImpl *N, *Src; - // Only dequeue from the "loops" worklist if WL1 has no items. // Thus we prioritize for paths that don't span loop boundaries. - + const ExplodedNodeImpl *N, *Src; + if (WL1.empty()) { N = WL1_Loops.back().first; Src = WL1_Loops.back().second; @@ -227,7 +226,7 @@ ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources, while (!WL2.empty()) { - ExplodedNodeImpl* N = WL2.back(); + const ExplodedNodeImpl* N = WL2.back(); WL2.pop_back(); // Skip this node if we have already processed it. diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m index e01c994d31..b123d62337 100644 --- a/test/Analysis/NSString.m +++ b/test/Analysis/NSString.m @@ -194,7 +194,7 @@ void f12() { } - (id)notShared { - return [[SharedClass alloc] _init]; // expected-warning{{This violates the naming convention rules}} + return [[SharedClass alloc] _init]; // expected-warning{{[naming convention] leak of returned object}} } + (id)sharedInstance { diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m index 2b16ae8ad8..0ce283ff24 100644 --- a/test/Analysis/retain-release.m +++ b/test/Analysis/retain-release.m @@ -149,8 +149,8 @@ CFDateRef f6(int x) { CFDateRef f7() { CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); - CFRetain(date); //expected-warning{{leak}} - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); + CFRetain(date); + date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} return date; } -- 2.40.0