[PATCH] D9912: PR20958 Allow redeclaration of type-generic builtins

2017-08-10 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev added a comment.

Hi! Thanks for this patch.

We're building Android6 with Clang (in order to apply static analyzer on it), 
and without this patch we've 613 build failures. This patch helps to get rid of 
521 of those build failures (85%).

"Works for me".




Comment at: lib/Sema/SemaDecl.cpp:1758
+  }
+  
+  QualType QT1 = FPT->getParamType(0);

Trailing space



Comment at: lib/Sema/SemaDecl.cpp:1763
+  ArgTypes.push_back(QT2);
+  
+  if (QT1->isRealFloatingType() && QT2->isRealFloatingType()) {

Ditto



Comment at: lib/Sema/SemaDecl.cpp:1775
+<< II->getName()
+<< QT1.getAsString();  
+  return DefaultFunctionType;

Ditto



Comment at: lib/Sema/SemaDecl.cpp:1837
+  case Builtin::BI__builtin_isnan:
+  case Builtin::BI__builtin_signbit:
+Diag(Loc, diag::err_incorrect_args_builtin_redecl)

Ditto


https://reviews.llvm.org/D9912



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40073: [Analyzer] Non-determinism: don't sort indirect goto LabelDecl's by addresses

2017-11-15 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev created this revision.
Herald added subscribers: szepet, xazax.hun.

Current CFG is built in non-deterministic order due to the fact that indirect 
goto labels' declarations (LabelDecl's) are stored in the llvm::SmallSet 
container. LabelDecl's are pointers, whose order is not deterministic by 
design, and llvm::SmallSet sorts them by their non-deterministic addresses 
after "small" container is exceeded. This leads to non-deterministic processing 
of the elements of the
container.

The fix is to use llvm::SmallSetVector, which is deterministic by design.

The introduced test case was creduce'd from Android5 source file.

The test file contains 100 runs, in order to make the testing stable: different 
PLIST's are generated in 20% and 80% cases, correspondingly.


Repository:
  rL LLVM

https://reviews.llvm.org/D40073

Files:
  lib/Analysis/CFG.cpp
  test/Analysis/diagnostics/goto-label-determinism.cpp

Index: test/Analysis/diagnostics/goto-label-determinism.cpp
===
--- /dev/null
+++ test/Analysis/diagnostics/goto-label-determinism.cpp
@@ -0,0 +1,254 @@
+// RUN: %clang_analyze_cc1 -triple arm-unknown-linux-gnueabi -w -analyzer-checker=debug.ExprInspection %s -verify
+// RUN: for i in {1..100}; do %clang_analyze_cc1 -triple arm-unknown-linux-gnueabi -w -analyzer-checker=debug.ExprInspection -analyzer-config max-nodes=10433 %s -analyzer-output=plist-multi-file -o %t.${i}.plist; done ; for i in {1..100}; do FileCheck --input-file=%t.${i}.plist %s; done ; if [ `md5sum %t.*.plist | awk '{print $1}' | sort -u | wc -l` -gt 1 ] ; then exit 1 ; fi
+
+int f();
+void clang_analyzer_warnIfReached();
+struct A {
+  void **t;
+  int recursion() {
+&&L1;
+&&L2;
+&&L3;
+&&L4;
+&&L5;
+&&L6;
+&&L7;
+&&L8;
+&&L9;
+  L1:
+f() > recursion();
+  L2:
+goto *t[f()];
+  L3:
+clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}};
+  L4:
+  L5:
+  L6:
+  L7:
+  L8:
+  L9:
+return 0;
+  }
+};
+
+// CHECK: diagnostics
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   path
+// CHECK-NEXT:   
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+// CHECK-NEXT: edges
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:start
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line9
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line9
+// CHECK-NEXT:   col6
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:end
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col6
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+// CHECK-NEXT: edges
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:start
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col6
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:end
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+// CHECK-NEXT: edges
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:start
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:end
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line21
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line21
+// CHECK-NEXT:   col8
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+

[PATCH] D40073: [Analyzer] Non-determinism: don't sort indirect goto LabelDecl's by addresses

2017-11-15 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev updated this revision to Diff 123016.
ilya-palachev added a comment.

Slightly changed the number of max-nodes, since previous one was maximum 
possible on my local branch, and it doesn't work for upstream. The behavior 
with number 500 seems more stable. With it, we have 4 different types of 
PLIST's being generated: 14, 54, 8 and 24 times, correspondingly.


Repository:
  rL LLVM

https://reviews.llvm.org/D40073

Files:
  lib/Analysis/CFG.cpp
  test/Analysis/diagnostics/goto-label-determinism.cpp

Index: test/Analysis/diagnostics/goto-label-determinism.cpp
===
--- /dev/null
+++ test/Analysis/diagnostics/goto-label-determinism.cpp
@@ -0,0 +1,254 @@
+// RUN: %clang_analyze_cc1 -triple arm-unknown-linux-gnueabi -w -analyzer-checker=debug.ExprInspection %s -verify
+// RUN: for i in {1..100}; do %clang_analyze_cc1 -triple arm-unknown-linux-gnueabi -w -analyzer-checker=debug.ExprInspection -analyzer-config max-nodes=500 %s -analyzer-output=plist-multi-file -o %t.${i}.plist; done ; for i in {1..100}; do FileCheck --input-file=%t.${i}.plist %s; done ; if [ `md5sum %t.*.plist | awk '{print $1}' | sort -u | wc -l` -gt 1 ] ; then exit 1 ; fi
+
+int f();
+void clang_analyzer_warnIfReached();
+struct A {
+  void **t;
+  int recursion() {
+&&L1;
+&&L2;
+&&L3;
+&&L4;
+&&L5;
+&&L6;
+&&L7;
+&&L8;
+&&L9;
+  L1:
+f() > recursion();
+  L2:
+goto *t[f()];
+  L3:
+clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}};
+  L4:
+  L5:
+  L6:
+  L7:
+  L8:
+  L9:
+return 0;
+  }
+};
+
+// CHECK: diagnostics
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   path
+// CHECK-NEXT:   
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+// CHECK-NEXT: edges
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:start
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line9
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line9
+// CHECK-NEXT:   col6
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:end
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col6
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+// CHECK-NEXT: edges
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:start
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line17
+// CHECK-NEXT:   col6
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:end
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+// CHECK-NEXT: edges
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:start
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line19
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:end
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line21
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line21
+// CHECK-NEXT:   col8
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT: 
+// CHECK-NEXT:   
+// CHECK-NEXT:  
+// CHECK-NEXT:
+// CHECK-NEXT:
+// CHECK-NEXT: kindcontrol
+// CHECK-NEXT: edges
+// CHECK-NEXT:  
+// CHECK-NEXT:   
+// CHECK-NEXT:start
+// CHECK-NEXT: 
+// CHECK-NEXT:  
+// CHECK-NEXT:   line21
+// CHECK-NEXT:   col5
+// CHECK-NEXT:   file0
+// CHECK-NEXT:  
+// CHECK-NEXT:  
+// CHECK-NEXT:   line21
+// CHECK-NEXT:   col8
+// CHECK-NEXT:   file0
+// CHECK-NEXT:

[PATCH] D40073: [Analyzer] Non-determinism: don't sort indirect goto LabelDecl's by addresses

2017-11-20 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev updated this revision to Diff 123558.
ilya-palachev added a comment.

Ok, I agree, this test file is rather better.


https://reviews.llvm.org/D40073

Files:
  lib/Analysis/CFG.cpp
  test/Analysis/cfg-indirect-goto-determinism.cpp

Index: test/Analysis/cfg-indirect-goto-determinism.cpp
===
--- /dev/null
+++ test/Analysis/cfg-indirect-goto-determinism.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+
+void *target;
+int indirectBlockSuccessorDeterminism() {
+(void)&&L1;
+(void)&&L2;
+(void)&&L3;
+(void)&&L4;
+(void)&&L5;
+(void)&&L6;
+(void)&&L7;
+(void)&&L8;
+(void)&&L9;
+(void)&&L10;
+(void)&&L11;
+(void)&&L12;
+(void)&&L13;
+(void)&&L14;
+(void)&&L15;
+(void)&&L16;
+(void)&&L17;
+(void)&&L18;
+(void)&&L19;
+(void)&&L20;
+(void)&&L21;
+(void)&&L22;
+(void)&&L23;
+(void)&&L24;
+(void)&&L25;
+(void)&&L26;
+(void)&&L27;
+(void)&&L28;
+(void)&&L29;
+(void)&&L30;
+(void)&&L31;
+(void)&&L32;
+(void)&&L33;
+(void)&&L34;
+(void)&&L35;
+(void)&&L36;
+(void)&&L37;
+(void)&&L38;
+(void)&&L39;
+(void)&&L40;
+
+goto *target;
+  L1:
+  L2:
+  L3:
+  L4:
+  L5:
+  L6:
+  L7:
+  L8:
+  L9:
+  L10:
+  L11:
+  L12:
+  L13:
+  L14:
+  L15:
+  L16:
+  L17:
+  L18:
+  L19:
+  L20:
+  L21:
+  L22:
+  L23:
+  L24:
+  L25:
+  L26:
+  L27:
+  L28:
+  L29:
+  L30:
+  L31:
+  L32:
+  L33:
+  L34:
+  L35:
+  L36:
+  L37:
+  L38:
+  L39:
+  L40:
+return 0;
+}
+
+// CHECK-LABEL:  [B41 (INDIRECT GOTO DISPATCH)]
+// CHECK-NEXT:   Preds (1): B42
+// CHECK-NEXT:  Succs (40): B1 B2 B3 B4 B5 B6 B7 B8
+// CHECK-NEXT:   B9 B10 B11 B12 B13 B14 B15 B16 B17 B18
+// CHECK-NEXT:   B19 B20 B21 B22 B23 B24 B25 B26 B27 B28
+// CHECK-NEXT:   B29 B30 B31 B32 B33 B34 B35 B36 B37 B38
+// CHECK-NEXT:   B39 B40
Index: lib/Analysis/CFG.cpp
===
--- lib/Analysis/CFG.cpp
+++ lib/Analysis/CFG.cpp
@@ -420,7 +420,7 @@
   BackpatchBlocksTy BackpatchBlocks;
 
   // A list of labels whose address has been taken (for indirect gotos).
-  typedef llvm::SmallPtrSet LabelSetTy;
+  typedef llvm::SmallSetVector LabelSetTy;
   LabelSetTy AddressTakenLabels;
 
   bool badCFG;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27710: [analyzer] Prohibit ExplodedGraph's edges duplicating

2016-12-21 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev added a comment.

In https://reviews.llvm.org/D27710#628069, @zaks.anna wrote:

> Are there any negative effects from having the duplicates in edges?


Yes, you're right; in current implementation there seems to be no negative 
effects from this, since duplicate edges are quite rare, and they produce very 
small overhead on memory (just two additional pointers for each excessive edge).

> When does this occur? It's a bit suspicious since we have a FromN, and a path 
> is split at that node, resulting in successors that are the same. Is it 
> possible that whoever split the state did not encode enough interesting info?

Yes, this  does occur (for one of our checkers on Android).
This patch is more likely a request for comments for what to do in the 
situation discussed below...

Consider the checker that can emit warnings on multiple dead symbols (one 
warning for each buggy symbol). When the checker encounters such situation, it 
first emits a warning for the 1st symbol, then for the 2nd one. For the 2nd and 
other symbols the CheckerContext::addTransition returns `nullptr'. That means 
that the requested node already exist, because the State hasn't changed. And 
for each warning beginning from the 2nd, the additional edge is added for the 
ExplodedGraph. It can be even simply seen with DOT graph.

Yes, this problem can be resolved with checker tags for nodes, but in this case 
we'll need to create new tag for each such warning (because ProgramPoint and 
ProgramState are equal for them all).

Moreover, such cases can even lead to non-determinism in warnings.

The checker stores a set(map/list...) of buggy symbols (regions...) in GDM. 
When checkDeadSymbols callback happens, this set is iterated, and the checker 
tries to emit a warning for each of them. But actually the order in which 
symbols are stored in the set depends on their order as pointers, and it's 
controlled by allocator. The allocator contains non-determinism by design, and 
region for symbol A can be greater (as a pointer) that the region for the 
symbol B in one analysis run, and smaller during the another run.

That's why in such cases different warnings can be emitted from time to time. 
The discussed patch doesn't address this issue, but I'd like at least to 
discuss the situation.


Repository:
  rL LLVM

https://reviews.llvm.org/D27710



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27710: [analyzer] Prohibit ExplodedGraph's edges duplicating

2017-01-19 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev added a comment.

Thanks for review!

> As Artem points out, the checkers in tree do not create a node for every bug 
> reported - there is no reason to do that.

Yes... But why does `generateNonFatalErrorNode` return `nullptr` in case when 
the node already exists? Isn't it designed so that to prevent multiple reports 
being thrown for the same node? If so, then the code contains a lot of such 
checks.

I don't understand why the following test passes, because each of two checkers: 
`MallocChecker` and `SimpleStreamChecker` are using `generateNonFatalErrorNode` 
method:

  // RUN: %clang_cc1 -analyze 
-analyzer-checker=unix.Malloc,alpha.unix.SimpleStream -analyzer-store region 
-verify %s
  
  typedef struct _IO_FILE FILE;
  extern FILE *fopen(const char *path, const char *mode);
  extern int fclose(FILE *fp);
  
  typedef __typeof(sizeof(int)) size_t;
  void *malloc(size_t);
  void free(void *);
  
  void test() {
void *p = malloc(1);
void *r = fopen("foo", "r");
if (r) {
  (void)(p - r);
  // expected-warning@-1{{Potential leak of memory}}
  // expected-warning@-2{{Opened file is never closed}}
}
else {
  fclose(r);
  free(p);
}
  }

Maybe it's possible to invent such a testcase when two checkers begin to 
conflict for the node. Or not?


Repository:
  rL LLVM

https://reviews.llvm.org/D27710



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27710: [analyzer] Prohibit ExplodedGraph's edges duplicating

2017-02-09 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev abandoned this revision.
ilya-palachev added a comment.

Ok, then, if you see no problem in dual edges, I'm abandoning this revision.


Repository:
  rL LLVM

https://reviews.llvm.org/D27710



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D27710: [analyzer] Prohibit ExplodedGraph's edges duplicating

2016-12-13 Thread Ilya Palachev via Phabricator via cfe-commits
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


[PATCH] D27710: [analyzer] Prohibit ExplodedGraph's edges duplicating

2016-12-13 Thread Ilya Palachev via Phabricator via cfe-commits
ilya-palachev removed rL LLVM as the repository for this revision.
ilya-palachev updated this revision to Diff 81221.
ilya-palachev added a comment.

Fixed a typo


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 : V->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 : V->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