<div dir="ltr"><div>Hi Csaba,</div><div><br></div>Failing example attached. Note that the output is different every time so there is potentially more than one failure mode.<div><br></div><div>Thanks</div><div>Russ</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 30 May 2019 at 15:05, Csaba Dabis <<a href="mailto:dabis.csaba98@gmail.com">dabis.csaba98@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hey!<div><br></div><div>When it fails, could you provide the DOT dump? The path is: llvm-project/build/tools/clang/test/Analysis/Output/dump_egraph.cpp.tmp.dot</div><div><br></div><div>Thanks,</div><div>Csaba.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, May 30, 2019 at 4:00 PM Russell Gallop <<a href="mailto:russell.gallop@gmail.com" target="_blank">russell.gallop@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi Csaba,<div><br></div><div>The test dump_egraph.cpp appears to be flaky on Windows. For example here: <a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/26183" target="_blank">http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/26183</a>.</div><br>C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.src\tools\clang\test\Analysis\dump_egraph.cpp:23:11: error: CHECK: expected string not found in input<br>// CHECK: \"store\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"cluster\": \"t\", \"items\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"Default\", \"offset\": 0, \"value\": \"conj_$3\{int, LC3, no stmt, #1\}\"<br><div><br></div><div>Running locally, it fails after 2-5 runs for me, running:</div><div><div>python bin/llvm-lit.py -v ../clang/test/Analysis/dump_egraph.cpp<br></div></div><div><br></div><div>Please could you take a look?</div><div><br></div><div>Note that I'm not certain it was this commit that started the flakiness, it is the latest which changed the failing line.</div><div><br></div><div>Thanks</div><div>Russ</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 29 May 2019 at 19:02, Csaba Dabis via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: charusso<br>
Date: Wed May 29 11:05:53 2019<br>
New Revision: 361997<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=361997&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=361997&view=rev</a><br>
Log:<br>
[analyzer] print() JSONify: getNodeLabel implementation<br>
<br>
Summary: This patch also rewrites the ProgramPoint printing.<br>
<br>
Reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus<br>
<br>
Reviewed By: NoQ<br>
<br>
Subscribers: cfe-commits, szepet, rnkovacs, a.sidorin, mikhail.ramalho,<br>
             donat.nagy, dkrupp<br>
<br>
Tags: #clang<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D62346" rel="noreferrer" target="_blank">https://reviews.llvm.org/D62346</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Analysis/ProgramPoint.h<br>
    cfe/trunk/lib/Analysis/ProgramPoint.cpp<br>
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
    cfe/trunk/test/Analysis/dump_egraph.c<br>
    cfe/trunk/test/Analysis/dump_egraph.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Analysis/ProgramPoint.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=361997&r1=361996&r2=361997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=361997&r1=361996&r2=361997&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Analysis/ProgramPoint.h (original)<br>
+++ cfe/trunk/include/clang/Analysis/ProgramPoint.h Wed May 29 11:05:53 2019<br>
@@ -213,7 +213,7 @@ public:<br>
     ID.AddPointer(getTag());<br>
   }<br>
<br>
-  void print(StringRef CR, llvm::raw_ostream &Out) const;<br>
+  void printJson(llvm::raw_ostream &Out, const char *NL = "\n") const;<br>
<br>
   LLVM_DUMP_METHOD void dump() const;<br>
<br>
<br>
Modified: cfe/trunk/lib/Analysis/ProgramPoint.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ProgramPoint.cpp?rev=361997&r1=361996&r2=361997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ProgramPoint.cpp?rev=361997&r1=361996&r2=361997&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Analysis/ProgramPoint.cpp (original)<br>
+++ cfe/trunk/lib/Analysis/ProgramPoint.cpp Wed May 29 11:05:53 2019<br>
@@ -43,151 +43,152 @@ ProgramPoint ProgramPoint::getProgramPoi<br>
 }<br>
<br>
 LLVM_DUMP_METHOD void ProgramPoint::dump() const {<br>
-  return print(/*CR=*/"\n", llvm::errs());<br>
+  return printJson(llvm::errs());<br>
 }<br>
<br>
-static void printLocation(raw_ostream &Out, SourceLocation SLoc,<br>
-                          const SourceManager &SM,<br>
-                          StringRef CR,<br>
-                          StringRef Postfix) {<br>
-  if (SLoc.isFileID()) {<br>
-    Out << CR << "line=" << SM.getExpansionLineNumber(SLoc)<br>
-        << " col=" << SM.getExpansionColumnNumber(SLoc) << Postfix;<br>
+static void printLocation(raw_ostream &Out, SourceLocation Loc,<br>
+                          const SourceManager &SM) {<br>
+  Out << "\"location\": ";<br>
+  if (!Loc.isFileID()) {<br>
+    Out << "null";<br>
+    return;<br>
   }<br>
+<br>
+  Out << "{ \"line\": " << SM.getExpansionLineNumber(Loc)<br>
+      << ", \"column\": " << SM.getExpansionColumnNumber(Loc) << " }";<br>
 }<br>
<br>
-void ProgramPoint::print(StringRef CR, llvm::raw_ostream &Out) const {<br>
+void ProgramPoint::printJson(llvm::raw_ostream &Out, const char *NL) const {<br>
   const ASTContext &Context =<br>
       getLocationContext()->getAnalysisDeclContext()->getASTContext();<br>
   const SourceManager &SM = Context.getSourceManager();<br>
+<br>
+  Out << "\"kind\": \"";<br>
   switch (getKind()) {<br>
   case ProgramPoint::BlockEntranceKind:<br>
-    Out << "Block Entrance: B"<br>
+    Out << "BlockEntrance\""<br>
+        << ", \"block_id\": "<br>
         << castAs<BlockEntrance>().getBlock()->getBlockID();<br>
     break;<br>
<br>
   case ProgramPoint::FunctionExitKind: {<br>
     auto FEP = getAs<FunctionExitPoint>();<br>
-    Out << "Function Exit: B" << FEP->getBlock()->getBlockID();<br>
+    Out << "FunctionExit\""<br>
+        << ", \"block_id\": " << FEP->getBlock()->getBlockID()<br>
+        << ", \"stmt_id\": ";<br>
+<br>
     if (const ReturnStmt *RS = FEP->getStmt()) {<br>
-      Out << CR << " Return: S" << RS->getID(Context) << CR;<br>
-      RS->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),<br>
-                      /*Indentation=*/2, /*NewlineSymbol=*/CR);<br>
+      Out << RS->getID(Context) << ", \"stmt\": \"";<br>
+      RS->printPretty(Out, /*Helper=*/nullptr, Context.getPrintingPolicy());<br>
+      Out << '\"';<br>
+    } else {<br>
+      Out << "null, \"stmt\": null";<br>
     }<br>
     break;<br>
   }<br>
   case ProgramPoint::BlockExitKind:<br>
-    assert(false);<br>
+    llvm_unreachable("BlockExitKind");<br>
     break;<br>
-<br>
   case ProgramPoint::CallEnterKind:<br>
-    Out << "CallEnter";<br>
+    Out << "CallEnter\"";<br>
     break;<br>
-<br>
   case ProgramPoint::CallExitBeginKind:<br>
-    Out << "CallExitBegin";<br>
+    Out << "CallExitBegin\"";<br>
     break;<br>
-<br>
   case ProgramPoint::CallExitEndKind:<br>
-    Out << "CallExitEnd";<br>
+    Out << "CallExitEnd\"";<br>
     break;<br>
-<br>
   case ProgramPoint::PostStmtPurgeDeadSymbolsKind:<br>
-    Out << "PostStmtPurgeDeadSymbols";<br>
+    Out << "PostStmtPurgeDeadSymbols\"";<br>
     break;<br>
-<br>
   case ProgramPoint::PreStmtPurgeDeadSymbolsKind:<br>
-    Out << "PreStmtPurgeDeadSymbols";<br>
+    Out << "PreStmtPurgeDeadSymbols\"";<br>
     break;<br>
-<br>
   case ProgramPoint::EpsilonKind:<br>
-    Out << "Epsilon Point";<br>
+    Out << "EpsilonPoint\"";<br>
     break;<br>
<br>
-  case ProgramPoint::LoopExitKind: {<br>
-    LoopExit LE = castAs<LoopExit>();<br>
-    Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();<br>
+  case ProgramPoint::LoopExitKind:<br>
+    Out << "LoopExit\", \"stmt\": \""<br>
+        << castAs<LoopExit>().getLoopStmt()->getStmtClassName() << '\"';<br>
     break;<br>
-  }<br>
<br>
   case ProgramPoint::PreImplicitCallKind: {<br>
     ImplicitCallPoint PC = castAs<ImplicitCallPoint>();<br>
-    Out << "PreCall: ";<br>
+    Out << "PreCall\", \"stmt\": \"";<br>
     PC.getDecl()->print(Out, Context.getLangOpts());<br>
-    printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);<br>
+    Out << "\", ";<br>
+    printLocation(Out, PC.getLocation(), SM);<br>
     break;<br>
   }<br>
<br>
   case ProgramPoint::PostImplicitCallKind: {<br>
     ImplicitCallPoint PC = castAs<ImplicitCallPoint>();<br>
-    Out << "PostCall: ";<br>
+    Out << "PostCall\", \"stmt\": \"";<br>
     PC.getDecl()->print(Out, Context.getLangOpts());<br>
-    printLocation(Out, PC.getLocation(), SM, CR, /*Postfix=*/CR);<br>
+    Out << "\", ";<br>
+    printLocation(Out, PC.getLocation(), SM);<br>
     break;<br>
   }<br>
<br>
   case ProgramPoint::PostInitializerKind: {<br>
-    Out << "PostInitializer: ";<br>
+    Out << "PostInitializer\", ";<br>
     const CXXCtorInitializer *Init = castAs<PostInitializer>().getInitializer();<br>
-    if (const FieldDecl *FD = Init->getAnyMember())<br>
-      Out << *FD;<br>
-    else {<br>
+    if (const FieldDecl *FD = Init->getAnyMember()) {<br>
+      Out << "\"field_decl\": \"" << *FD << '\"';<br>
+    } else {<br>
+      Out << "\"type\": \"";<br>
       QualType Ty = Init->getTypeSourceInfo()->getType();<br>
       Ty = Ty.getLocalUnqualifiedType();<br>
       Ty.print(Out, Context.getLangOpts());<br>
+      Out << '\"';<br>
     }<br>
     break;<br>
   }<br>
<br>
   case ProgramPoint::BlockEdgeKind: {<br>
     const BlockEdge &E = castAs<BlockEdge>();<br>
-    Out << "Edge: (B" << E.getSrc()->getBlockID() << ", B"<br>
-        << E.getDst()->getBlockID() << ')';<br>
-<br>
-    if (const Stmt *T = E.getSrc()->getTerminatorStmt()) {<br>
-      SourceLocation SLoc = T->getBeginLoc();<br>
-<br>
-      Out << "\\|Terminator: ";<br>
-      E.getSrc()->printTerminator(Out, Context.getLangOpts());<br>
-      printLocation(Out, SLoc, SM, CR, /*Postfix=*/"");<br>
-<br>
-      if (isa<SwitchStmt>(T)) {<br>
-        const Stmt *Label = E.getDst()->getLabel();<br>
-<br>
-        if (Label) {<br>
-          if (const auto *C = dyn_cast<CaseStmt>(Label)) {<br>
-            Out << CR << "case ";<br>
-            if (C->getLHS())<br>
-              C->getLHS()->printPretty(<br>
-                  Out, nullptr, Context.getPrintingPolicy(),<br>
-                  /*Indentation=*/0, /*NewlineSymbol=*/CR);<br>
-<br>
-            if (const Stmt *RHS = C->getRHS()) {<br>
-              Out << " .. ";<br>
-              RHS->printPretty(Out, nullptr, Context.getPrintingPolicy(),<br>
-                               /*Indetation=*/0, /*NewlineSymbol=*/CR);<br>
-            }<br>
-<br>
-            Out << ":";<br>
-          } else {<br>
-            assert(isa<DefaultStmt>(Label));<br>
-            Out << CR << "default:";<br>
-          }<br>
-        } else<br>
-          Out << CR << "(implicit) default:";<br>
-      } else if (isa<IndirectGotoStmt>(T)) {<br>
-        // FIXME<br>
+    const Stmt *T = E.getSrc()->getTerminatorStmt();<br>
+    Out << "Edge\", \"src_id\": " << E.getSrc()->getBlockID()<br>
+        << ", \"dst_id\": " << E.getDst()->getBlockID()<br>
+        << ", \"terminator\": " << (!T ? "null, \"term_kind\": null" : "\"");<br>
+    if (!T)<br>
+      break;<br>
+<br>
+    E.getSrc()->printTerminator(Out, Context.getLangOpts());<br>
+    Out << "\", ";<br>
+    printLocation(Out, T->getBeginLoc(), SM);<br>
+    Out << ", \"term_kind\": \"";<br>
+<br>
+    if (isa<SwitchStmt>(T)) {<br>
+      Out << "SwitchStmt\", \"case\": ";<br>
+      if (const Stmt *Label = E.getDst()->getLabel()) {<br>
+        if (const auto *C = dyn_cast<CaseStmt>(Label)) {<br>
+          Out << "{ \"lhs\": ";<br>
+          if (const Stmt *LHS = C->getLHS())<br>
+            LHS->printPretty(Out, nullptr, Context.getPrintingPolicy());<br>
+          else<br>
+            Out << "null";<br>
+          Out << ", \"rhs\": ";<br>
+          if (const Stmt *RHS = C->getRHS())<br>
+            RHS->printPretty(Out, nullptr, Context.getPrintingPolicy());<br>
+          else<br>
+            Out << "null";<br>
+          Out << " }";<br>
+        } else {<br>
+          assert(isa<DefaultStmt>(Label));<br>
+          Out << "\"default\"";<br>
+        }<br>
       } else {<br>
-        Out << CR << "Condition: ";<br>
-        if (*E.getSrc()->succ_begin() == E.getDst())<br>
-          Out << "true";<br>
-        else<br>
-          Out << "false";<br>
+        Out << "\"implicit default\"";<br>
       }<br>
-<br>
-      Out << CR;<br>
+    } else if (isa<IndirectGotoStmt>(T)) {<br>
+      // FIXME: More info.<br>
+      Out << "IndirectGotoStmt\"";<br>
+    } else {<br>
+      Out << "Condition\", \"value\": "<br>
+          << (*E.getSrc()->succ_begin() == E.getDst() ? "true" : "false");<br>
     }<br>
-<br>
     break;<br>
   }<br>
<br>
@@ -195,22 +196,37 @@ void ProgramPoint::print(StringRef CR, l<br>
     const Stmt *S = castAs<StmtPoint>().getStmt();<br>
     assert(S != nullptr && "Expecting non-null Stmt");<br>
<br>
-    Out << S->getStmtClassName() << " S" << S->getID(Context) << " <"<br>
-        << (const void *)S << "> ";<br>
-    S->printPretty(Out, /*helper=*/nullptr, Context.getPrintingPolicy(),<br>
-                   /*Indentation=*/2, /*NewlineSymbol=*/CR);<br>
-    printLocation(Out, S->getBeginLoc(), SM, CR, /*Postfix=*/"");<br>
+    llvm::SmallString<256> TempBuf;<br>
+    llvm::raw_svector_ostream TempOut(TempBuf);<br>
+<br>
+    Out << "Statement\", \"stmt_kind\": \"" << S->getStmtClassName()<br>
+        << "\", \"stmt_id\": " << S->getID(Context)<br>
+        << ", \"pointer\": \"" << (const void *)S << "\", \"pretty\": ";<br>
+<br>
+    // See whether the current statement is pretty-printable.<br>
+    S->printPretty(TempOut, /*Helper=*/nullptr, Context.getPrintingPolicy());<br>
+    if (!TempBuf.empty()) {<br>
+      Out << '\"' << TempBuf.str().trim() << "\", ";<br>
+      TempBuf.clear();<br>
+    } else {<br>
+      Out << "null, ";<br>
+    }<br>
+<br>
+    printLocation(Out, S->getBeginLoc(), SM);<br>
<br>
+    Out << ", \"stmt_point_kind\": ";<br>
     if (getAs<PreStmt>())<br>
-      Out << CR << "PreStmt" << CR;<br>
+      Out << "\"PreStmt\"";<br>
     else if (getAs<PostLoad>())<br>
-      Out << CR << "PostLoad" << CR;<br>
+      Out << "\"PostLoad\"";<br>
     else if (getAs<PostStore>())<br>
-      Out << CR << "PostStore" << CR;<br>
+      Out << "\"PostStore\"";<br>
     else if (getAs<PostLValue>())<br>
-      Out << CR << "PostLValue" << CR;<br>
+      Out << "\"PostLValue\"";<br>
     else if (getAs<PostAllocatorCall>())<br>
-      Out << CR << "PostAllocatorCall" << CR;<br>
+      Out << "\"PostAllocatorCall\"";<br>
+    else<br>
+      Out << "null";<br>
<br>
     break;<br>
   }<br>
<br>
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=361997&r1=361996&r2=361997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=361997&r1=361996&r2=361997&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)<br>
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed May 29 11:05:53 2019<br>
@@ -162,12 +162,12 @@ public:<br>
         << "\", \"argument_index\": ";<br>
<br>
     if (getItem().getKind() == ConstructionContextItem::ArgumentKind)<br>
-      Out << getItem().getIndex() << '\"';<br>
+      Out << getItem().getIndex();<br>
     else<br>
       Out << "null";<br>
<br>
     // Pretty-print<br>
-    Out << ", \"pretty\": \"";<br>
+    Out << ", \"pretty\": ";<br>
<br>
     if (S) {<br>
       llvm::SmallString<256> TempBuf;<br>
@@ -176,13 +176,13 @@ public:<br>
       // See whether the current statement is pretty-printable.<br>
       S->printPretty(TempOut, Helper, PP);<br>
       if (!TempBuf.empty()) {<br>
-        Out << TempBuf.str().trim() << '\"';<br>
+        Out << '\"' << TempBuf.str().trim() << '\"';<br>
         TempBuf.clear();<br>
       } else {<br>
         Out << "null";<br>
       }<br>
     } else {<br>
-      Out << I->getAnyMember()->getNameAsString() << '\"';<br>
+      Out << '\"' << I->getAnyMember()->getNameAsString() << '\"';<br>
     }<br>
   }<br>
<br>
@@ -3079,37 +3079,55 @@ struct DOTGraphTraits<ExplodedGraph*> :<br>
   }<br>
<br>
   static std::string getNodeLabel(const ExplodedNode *N, ExplodedGraph *G){<br>
-    std::string sbuf;<br>
-    llvm::raw_string_ostream Out(sbuf);<br>
+    std::string Buf;<br>
+    llvm::raw_string_ostream Out(Buf);<br>
<br>
+    const bool IsDot = true;<br>
+    const unsigned int Space = 1;<br>
     ProgramStateRef State = N->getState();<br>
<br>
+    Out << "{ \"node_id\": \"" << (const void *)N<br>
+        << "\", \"state_id\": " << State->getID()<br>
+        << ", \"has_report\": " << (nodeHasBugReport(N) ? "true" : "false")<br>
+        << ",\\l";<br>
+<br>
+    Indent(Out, Space, IsDot) << "\"program_points\": [\\l";<br>
+<br>
     // Dump program point for all the previously skipped nodes.<br>
     traverseHiddenNodes(<br>
         N,<br>
         [&](const ExplodedNode *OtherNode) {<br>
-          OtherNode->getLocation().print(/*CR=*/"\\l", Out);<br>
+          Indent(Out, Space + 1, IsDot) << "{ ";<br>
+          OtherNode->getLocation().printJson(Out, /*NL=*/"\\l");<br>
+          Out << ", \"tag\": ";<br>
           if (const ProgramPointTag *Tag = OtherNode->getLocation().getTag())<br>
-            Out << "\\lTag:" << Tag->getTagDescription();<br>
-          if (N->isSink())<br>
-            Out << "\\lNode is sink\\l";<br>
-          if (nodeHasBugReport(N))<br>
-            Out << "\\lBug report attached\\l";<br>
+            Out << '\"' << Tag->getTagDescription() << "\" }";<br>
+          else<br>
+            Out << "null }";<br>
         },<br>
-        [&](const ExplodedNode *) { Out << "\\l--------\\l"; },<br>
+       // Adds a comma and a new-line between each program point.<br>
+        [&](const ExplodedNode *) { Out << ",\\l"; },<br>
         [&](const ExplodedNode *) { return false; });<br>
<br>
-    Out << "\\l\\|";<br>
-<br>
-    Out << "StateID: ST" << State->getID() << ", NodeID: N" << N->getID(G)<br>
-        << " <" << (const void *)N << ">\\|";<br>
+    Out << "\\l"; // Adds a new-line to the last program point.<br>
+    Indent(Out, Space, IsDot) << "],\\l";<br>
<br>
     bool SameAsAllPredecessors =<br>
         std::all_of(N->pred_begin(), N->pred_end(), [&](const ExplodedNode *P) {<br>
           return P->getState() == State;<br>
         });<br>
-    if (!SameAsAllPredecessors)<br>
-      State->printDOT(Out, N->getLocationContext());<br>
+<br>
+    if (!SameAsAllPredecessors) {<br>
+      State->printDOT(Out, N->getLocationContext(), Space);<br>
+    } else {<br>
+      Indent(Out, Space, IsDot) << "\"program_state\": null";<br>
+    }<br>
+<br>
+    Out << "\\l}";<br>
+    if (!N->succ_empty())<br>
+      Out << ',';<br>
+    Out << "\\l";<br>
+<br>
     return Out.str();<br>
   }<br>
 };<br>
<br>
Modified: cfe/trunk/test/Analysis/dump_egraph.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dump_egraph.c?rev=361997&r1=361996&r2=361997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dump_egraph.c?rev=361997&r1=361996&r2=361997&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Analysis/dump_egraph.c (original)<br>
+++ cfe/trunk/test/Analysis/dump_egraph.c Wed May 29 11:05:53 2019<br>
@@ -11,6 +11,10 @@ int foo() {<br>
 }<br>
<br>
 // CHECK: digraph "Exploded Graph" {<br>
-// CHECK: Edge: (B2, B1)<br>
-// CHECK: Block Entrance: B1<br>
-// CHECK: Bug report attached<br>
+<br>
+// CHECK: \"program_points\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"Edge\", \"src_id\": 2, \"dst_id\": 1, \"terminator\": null, \"term_kind\": null, \"tag\": null \}\l&nbsp;&nbsp;],\l&nbsp;&nbsp;\"program_state\": null<br>
+<br>
+// CHECK: \"program_points\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"BlockEntrance\", \"block_id\": 1<br>
+<br>
+// CHECK: \"has_report\": true<br>
+<br>
<br>
Modified: cfe/trunk/test/Analysis/dump_egraph.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dump_egraph.cpp?rev=361997&r1=361996&r2=361997&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dump_egraph.cpp?rev=361997&r1=361996&r2=361997&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Analysis/dump_egraph.cpp (original)<br>
+++ cfe/trunk/test/Analysis/dump_egraph.cpp Wed May 29 11:05:53 2019<br>
@@ -16,9 +16,9 @@ void foo() {<br>
   T t;<br>
 }<br>
<br>
-// CHECK: \"constructing_objects\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"location_context\": \"#0 Call\", \"calling\": \"foo\", \"call_line\": null, \"items\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"lctx_id\": 1, \"stmt_id\": 1155, \"kind\": \"construct into local variable\", \"argument_index\": null, \"pretty\": \"T t;\", \"value\": \"&t\"<br>
+// CHECK: \"constructing_objects\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"location_context\": \"#0 Call\", \"calling\": \"foo\", \"call_line\": null, \"items\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"lctx_id\": 1, \"stmt_id\": 1155, \"kind\": \"construct into local variable\", \"argument_index\": null, \"pretty\": \"T t;\", \"value\": \"&t\"<br>
<br>
-// CHECK: \"constructing_objects\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"location_context\": \"#0 Call\", \"calling\": \"T::T\", \"call_line\": \"16\", \"items\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"lctx_id\": 2, \"init_id\": 1092, \"kind\": \"construct into member variable\", \"argument_index\": null, \"pretty\": \"s\", \"value\": \"&t-\>s\"<br>
+// CHECK: \"constructing_objects\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"location_context\": \"#0 Call\", \"calling\": \"T::T\", \"call_line\": \"16\", \"items\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"lctx_id\": 2, \"init_id\": 1092, \"kind\": \"construct into member variable\", \"argument_index\": null, \"pretty\": \"s\", \"value\": \"&t-\>s\"<br>
<br>
-// CHECK: \"store\": [\l&nbsp;&nbsp;&nbsp;&nbsp;\{ \"cluster\": \"t\", \"items\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"Default\", \"offset\": 0, \"value\": \"conj_$3\{int, LC3, no stmt, #1\}\"<br>
+// CHECK: \"store\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"cluster\": \"t\", \"items\": [\l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\{ \"kind\": \"Default\", \"offset\": 0, \"value\": \"conj_$3\{int, LC3, no stmt, #1\}\"<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>
</blockquote></div>
</blockquote></div>