r342413 - [analyzer] ExplodedGraph printing fixes

George Karpenkov via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 17 13:46:54 PDT 2018


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
 }




More information about the cfe-commits mailing list