Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h =================================================================== --- clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -461,12 +461,15 @@ namespace llvm { - template<> struct GraphTraits { + template <> struct GraphTraits { + using GraphTy = clang::ento::ExplodedGraph *; using NodeRef = clang::ento::ExplodedNode *; using ChildIteratorType = clang::ento::ExplodedNode::succ_iterator; - using nodes_iterator = llvm::df_iterator; + using nodes_iterator = llvm::df_iterator; - static NodeRef getEntryNode(NodeRef N) { return N; } + static NodeRef getEntryNode(const GraphTy G) { + return *G->roots_begin(); + } static ChildIteratorType child_begin(NodeRef N) { if (N->succ_size() == 1 && (*N->succ_begin())->isTrivial()) { @@ -482,27 +485,14 @@ return N->succ_end(); } - static nodes_iterator nodes_begin(NodeRef N) { return df_begin(N); } - - static nodes_iterator nodes_end(NodeRef N) { return df_end(N); } - }; - - template<> struct GraphTraits { - using NodeRef = const clang::ento::ExplodedNode *; - using ChildIteratorType = clang::ento::ExplodedNode::const_succ_iterator; - using nodes_iterator = llvm::df_iterator; - - static NodeRef getEntryNode(NodeRef N) { return N; } - - static ChildIteratorType child_begin(NodeRef N) { return N->succ_begin(); } - - static ChildIteratorType child_end(NodeRef N) { return N->succ_end(); } - - static nodes_iterator nodes_begin(NodeRef N) { return df_begin(N); } + static nodes_iterator nodes_begin(const GraphTy G) { + return df_begin(G); + } - static nodes_iterator nodes_end(NodeRef N) { return df_end(N); } + static nodes_iterator nodes_end(const GraphTy G) { + return df_end(G); + } }; - } // namespace llvm #endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H Index: clang/lib/StaticAnalyzer/Core/BugReporter.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2420,8 +2420,8 @@ while (true) { // Create the equivalent node in the new graph with the same state // and location. - ExplodedNode *NewN = GNew->createUncachedNode(OrigN->getLocation(), OrigN->getState(), - OrigN->isSink()); + ExplodedNode *NewN = GNew->createUncachedNode( + OrigN->getLocation(), OrigN->getState(), OrigN->isSink()); // Store the mapping to the original node. InterExplodedGraphMap::const_iterator IMitr = InverseMap.find(OrigN); Index: clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp +++ clang/lib/StaticAnalyzer/Core/ExplodedGraph.cpp @@ -398,6 +398,7 @@ // Create the corresponding node in the new graph and record the mapping // from the old node to the new node. ExplodedNode *NewN = G->createUncachedNode(N->getLocation(), N->State, N->isSink()); + Pass2[N] = NewN; // Also record the reverse mapping from the new node to the old node. Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2947,28 +2947,28 @@ //===----------------------------------------------------------------------===// #ifndef NDEBUG -static ExprEngine* GraphPrintCheckerState; -static SourceManager* GraphPrintSourceManager; - namespace llvm { template<> -struct DOTGraphTraits : public DefaultDOTGraphTraits { +struct DOTGraphTraits : public DefaultDOTGraphTraits { DOTGraphTraits (bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {} // FIXME: Since we do not cache error nodes in ExprEngine now, this does not // work. - static std::string getNodeAttributes(const ExplodedNode *N, void*) { + static std::string getNodeAttributes(const ExplodedNode *N, + ExplodedGraph *G) { return {}; } // De-duplicate some source location pretty-printing. - static void printLocation(raw_ostream &Out, SourceLocation SLoc) { + static void printLocation(raw_ostream &Out, + SourceLocation SLoc, + const SourceManager &SM) { if (SLoc.isFileID()) { Out << "\\lline=" - << GraphPrintSourceManager->getExpansionLineNumber(SLoc) + << SM.getExpansionLineNumber(SLoc) << " col=" - << GraphPrintSourceManager->getExpansionColumnNumber(SLoc) + << SM.getExpansionColumnNumber(SLoc) << "\\l"; } } @@ -2976,6 +2976,7 @@ static void dumpProgramPoint(ProgramPoint Loc, const ASTContext &Context, llvm::raw_string_ostream &Out) { + const SourceManager &SM = Context.getSourceManager(); switch (Loc.getKind()) { case ProgramPoint::BlockEntranceKind: Out << "Block Entrance: B" @@ -3020,7 +3021,7 @@ ImplicitCallPoint PC = Loc.castAs(); Out << "PreCall: "; PC.getDecl()->print(Out, Context.getLangOpts()); - printLocation(Out, PC.getLocation()); + printLocation(Out, PC.getLocation(), SM); break; } @@ -3028,7 +3029,7 @@ ImplicitCallPoint PC = Loc.castAs(); Out << "PostCall: "; PC.getDecl()->print(Out, Context.getLangOpts()); - printLocation(Out, PC.getLocation()); + printLocation(Out, PC.getLocation(), SM); break; } @@ -3059,9 +3060,9 @@ if (SLoc.isFileID()) { Out << "\\lline=" - << GraphPrintSourceManager->getExpansionLineNumber(SLoc) + << SM.getExpansionLineNumber(SLoc) << " col=" - << GraphPrintSourceManager->getExpansionColumnNumber(SLoc); + << SM.getExpansionColumnNumber(SLoc); } if (isa(T)) { @@ -3112,7 +3113,7 @@ << S->getID(Context) << " <" << (const void *)S << "> "; S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(), /*Indentation=*/2, /*NewlineSymbol=*/"\\l"); - printLocation(Out, S->getBeginLoc()); + printLocation(Out, S->getBeginLoc(), SM); if (Loc.getAs()) Out << "\\lPreStmt\\l"; @@ -3134,7 +3135,7 @@ return N->isTrivial(); } - static std::string getNodeLabel(const ExplodedNode *N, void*){ + static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G){ std::string sbuf; llvm::raw_string_ostream Out(sbuf); @@ -3167,11 +3168,7 @@ Out << "\\l\\|"; - ExplodedGraph &Graph = - static_cast(State->getStateManager().getOwningEngine()) - ->getGraph(); - - Out << "StateID: ST" << State->getID() << ", NodeID: N" << N->getID(&Graph) + Out << "StateID: ST" << State->getID() << ", NodeID: N" << N->getID(G) << " <" << (const void *)N << ">\\|"; bool SameAsAllPredecessors = @@ -3205,32 +3202,20 @@ } ViewGraph(Src); - } - else { - GraphPrintCheckerState = this; - GraphPrintSourceManager = &getContext().getSourceManager(); - - llvm::ViewGraph(*G.roots_begin(), "ExprEngine"); - - GraphPrintCheckerState = nullptr; - GraphPrintSourceManager = nullptr; + } else { + llvm::ViewGraph(&G, "ExprEngine"); } #endif } void ExprEngine::ViewGraph(ArrayRef Nodes) { #ifndef NDEBUG - GraphPrintCheckerState = this; - GraphPrintSourceManager = &getContext().getSourceManager(); - std::unique_ptr TrimmedG(G.trim(Nodes)); - if (!TrimmedG.get()) + if (!TrimmedG.get()) { llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n"; - else - llvm::ViewGraph(*TrimmedG->roots_begin(), "TrimmedExprEngine"); - - GraphPrintCheckerState = nullptr; - GraphPrintSourceManager = nullptr; + } else { + llvm::ViewGraph(TrimmedG.get(), "TrimmedExprEngine"); + } #endif }