Author: george.karpenkov Date: Mon Sep 17 13:46:53 2018 New Revision: 342413
URL: http://llvm.org/viewvc/llvm-project?rev=342413&view=rev Log: [analyzer] ExplodedGraph printing fixes Fixes a number of issues: - Global variables are not used for communication - Trait should be defined on a graph, not on a node - Defining the trait on a graph allows us to use a correct allocator, no longer crashing while printing trimmed graphs Differential Revision: https://reviews.llvm.org/D52183 Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h?rev=342413&r1=342412&r2=342413&view=diff ============================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h (original) +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h Mon Sep 17 13:46:53 2018 @@ -461,12 +461,15 @@ public: namespace llvm { - template<> struct GraphTraits<clang::ento::ExplodedNode*> { + template <> struct GraphTraits<clang::ento::ExplodedGraph *> { + using GraphTy = clang::ento::ExplodedGraph *; using NodeRef = clang::ento::ExplodedNode *; using ChildIteratorType = clang::ento::ExplodedNode::succ_iterator; - using nodes_iterator = llvm::df_iterator<NodeRef>; + using nodes_iterator = llvm::df_iterator<GraphTy>; - 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 @@ namespace llvm { 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<const clang::ento::ExplodedNode*> { - using NodeRef = const clang::ento::ExplodedNode *; - using ChildIteratorType = clang::ento::ExplodedNode::const_succ_iterator; - using nodes_iterator = llvm::df_iterator<NodeRef>; - - 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 Modified: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp?rev=342413&r1=342412&r2=342413&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp Mon Sep 17 13:46:53 2018 @@ -226,7 +226,7 @@ void Environment::print(raw_ostream &Out PrintingPolicy PP = Context.getPrintingPolicy(); - Out << NL << NL << "Expressions by stack frame:" << NL; + Out << NL << "Expressions by stack frame:" << NL; WithLC->dumpStack(Out, "", NL, Sep, [&](const LocationContext *LC) { for (auto I : ExprBindings) { if (I.first.getLocationContext() != LC) Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=342413&r1=342412&r2=342413&view=diff ============================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original) +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Sep 17 13:46:53 2018 @@ -2947,35 +2947,37 @@ void ExprEngine::VisitMSAsmStmt(const MS //===----------------------------------------------------------------------===// #ifndef NDEBUG -static ExprEngine* GraphPrintCheckerState; -static SourceManager* GraphPrintSourceManager; - namespace llvm { template<> -struct DOTGraphTraits<ExplodedNode*> : public DefaultDOTGraphTraits { +struct DOTGraphTraits<ExplodedGraph*> : 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, + StringRef Postfix="\\l") { if (SLoc.isFileID()) { Out << "\\lline=" - << GraphPrintSourceManager->getExpansionLineNumber(SLoc) + << SM.getExpansionLineNumber(SLoc) << " col=" - << GraphPrintSourceManager->getExpansionColumnNumber(SLoc) - << "\\l"; + << SM.getExpansionColumnNumber(SLoc) + << Postfix; } } 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 +3022,7 @@ struct DOTGraphTraits<ExplodedNode*> : p ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>(); Out << "PreCall: "; PC.getDecl()->print(Out, Context.getLangOpts()); - printLocation(Out, PC.getLocation()); + printLocation(Out, PC.getLocation(), SM); break; } @@ -3028,7 +3030,7 @@ struct DOTGraphTraits<ExplodedNode*> : p ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>(); Out << "PostCall: "; PC.getDecl()->print(Out, Context.getLangOpts()); - printLocation(Out, PC.getLocation()); + printLocation(Out, PC.getLocation(), SM); break; } @@ -3056,13 +3058,7 @@ struct DOTGraphTraits<ExplodedNode*> : p Out << "\\|Terminator: "; E.getSrc()->printTerminator(Out, Context.getLangOpts()); - - if (SLoc.isFileID()) { - Out << "\\lline=" - << GraphPrintSourceManager->getExpansionLineNumber(SLoc) - << " col=" - << GraphPrintSourceManager->getExpansionColumnNumber(SLoc); - } + printLocation(Out, SLoc, SM, /*Postfix=*/""); if (isa<SwitchStmt>(T)) { const Stmt *Label = E.getDst()->getLabel(); @@ -3112,7 +3108,7 @@ struct DOTGraphTraits<ExplodedNode*> : p << 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, /*Postfix=*/""); if (Loc.getAs<PreStmt>()) Out << "\\lPreStmt\\l"; @@ -3134,7 +3130,7 @@ struct DOTGraphTraits<ExplodedNode*> : p 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 +3163,7 @@ struct DOTGraphTraits<ExplodedNode*> : p Out << "\\l\\|"; - ExplodedGraph &Graph = - static_cast<ExprEngine *>(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 +3197,20 @@ void ExprEngine::ViewGraph(bool trim) { } 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<const ExplodedNode*> Nodes) { #ifndef NDEBUG - GraphPrintCheckerState = this; - GraphPrintSourceManager = &getContext().getSourceManager(); - std::unique_ptr<ExplodedGraph> 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 } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits