ilya-palachev created this revision.
ilya-palachev added reviewers: NoQ, zaks.anna, dcoughlin.
ilya-palachev added subscribers: cfe-commits, a.sidorin, ilya-palachev.
ilya-palachev set the repository for this revision to rL LLVM.

Current implementation doesn't take care about the duplicates in edges
of ExplodedGraph. This actually happens when, for example, the checker
tries to add transition to node, and gets `nullptr', which means that
the node already exists and has been processed. In this case edge
between the node and its predecessor is duplicated.

This patch prohibits this situation, by checking whether the actual
group already contains the given predecessor.


Repository:
  rL LLVM

https://reviews.llvm.org/D27710

Files:
  lib/StaticAnalyzer/Core/CoreEngine.cpp
  lib/StaticAnalyzer/Core/ExplodedGraph.cpp


Index: lib/StaticAnalyzer/Core/ExplodedGraph.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -215,6 +215,11 @@
 
 void ExplodedNode::addPredecessor(ExplodedNode *V, ExplodedGraph &G) {
   assert (!V->isSink());
+  for (ExplodedNode *N : Preds)
+    assert(N != V && "Edge already exists");
+  for (ExplodedNode *N : Succs)
+    assert(N != this && "Edge already exists");
+
   Preds.addNode(V, G);
   V->Succs.addNode(this, G);
 #ifndef NDEBUG
Index: lib/StaticAnalyzer/Core/CoreEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -657,7 +657,17 @@
   HasGeneratedNodes = true;
   bool IsNew;
   ExplodedNode *N = C.Eng.G.getNode(Loc, State, MarkAsSink, &IsNew);
-  N->addPredecessor(FromN, C.Eng.G);
+
+  bool EdgeExists = false;
+  for (auto I = N->pred_begin(), E = N->pred_end(); I != E; ++I)
+    if (*I == FromN) {
+      EdgeExists = true;
+      break;
+    }
+
+  if (!EdgeExists)
+    N->addPredecessor(FromN, C.Eng.G);
+
   Frontier.erase(FromN);
 
   if (!IsNew)


Index: lib/StaticAnalyzer/Core/ExplodedGraph.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -215,6 +215,11 @@
 
 void ExplodedNode::addPredecessor(ExplodedNode *V, ExplodedGraph &G) {
   assert (!V->isSink());
+  for (ExplodedNode *N : Preds)
+    assert(N != V && "Edge already exists");
+  for (ExplodedNode *N : Succs)
+    assert(N != this && "Edge already exists");
+
   Preds.addNode(V, G);
   V->Succs.addNode(this, G);
 #ifndef NDEBUG
Index: lib/StaticAnalyzer/Core/CoreEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -657,7 +657,17 @@
   HasGeneratedNodes = true;
   bool IsNew;
   ExplodedNode *N = C.Eng.G.getNode(Loc, State, MarkAsSink, &IsNew);
-  N->addPredecessor(FromN, C.Eng.G);
+
+  bool EdgeExists = false;
+  for (auto I = N->pred_begin(), E = N->pred_end(); I != E; ++I)
+    if (*I == FromN) {
+      EdgeExists = true;
+      break;
+    }
+
+  if (!EdgeExists)
+    N->addPredecessor(FromN, C.Eng.G);
+
   Frontier.erase(FromN);
 
   if (!IsNew)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to