dcoughlin added a comment.

> There is a loss of precision for loops that need to be executed exactly 
> maxBlockVisitOnPath times, as the loop body is executed with the widened 
> state instead of the last iteration.


I think this is an acceptable loss of precision because, in general, it is 
unlikely that a concrete-bounded loop will be executed *exactly* 
maxBlockVisitOnPath times. You could add special syntactic checks to try to 
detect this, but I think it is unlikely to make much different in practice.


================
Comment at: lib/StaticAnalyzer/Core/LoopWidening.cpp:64
@@ +63,3 @@
+  }
+  return PrevState->invalidateRegions(Regions, getLoopCondition(LoopStmt),
+                                      BlockCount, LCtx, false, nullptr,
----------------
Passing `true` here instead of `false` for `CausedByPointerEscape` should fix 
the false alarm. This will cause invalidation to tell the MallocChecker that 
the pointer has escaped and so shouldn't be treated as a leak.

================
Comment at: test/Analysis/loop-widening.c:3
@@ +2,3 @@
+
+extern void clang_analyzer_eval(_Bool);
+extern void clang_analyzer_warnIfReached();
----------------
There seems to be some weirdness when using `_Bool` in the prototype (vs. int). 
It adds an extra `!= 0` to symbolic expressions, which can result in 
clang_analyzer_eval() yielding `UNKNOWN` when using `extern void 
clang_analyze_eval(int)` would print `TRUE` or `FALSE`.

We should track this down and fix it, but for now I think it is better to use 
`extern void clang_analyze_eval(int)`.

================
Comment at: test/Analysis/loop-widening.c:13
@@ +12,3 @@
+  int x = 1;
+  // Check loop isn't widened by checking x isn't invalidated
+  for (i = 0; i < 1; ++i) {}
----------------
This is clever.

================
Comment at: test/Analysis/loop-widening.c:111
@@ +110,3 @@
+  }
+  if (i < 50) {
+    clang_analyzer_warnIfReached(); // no-warning
----------------
After changing the `clang_analyzer_eval()` prototype to take an int, you can 
use `clang_analyzer_eval(i >= 50); // expected-warning {{TRUE}}`.

================
Comment at: test/Analysis/loop-widening.c:158
@@ +157,3 @@
+  clang_analyzer_eval(h_ptr); // expected-warning {{UNKNOWN}}
+  free(h_ptr);
+}
----------------
I think it would be good to add some nested loop tests. For example:


```
void nested1() {
  int i = 0, j = 0;
  for (i = 0; i < 10; i++) {
    clang_analyzer_eval(i < 10); // expected-warning {{TRUE}}
    for (j = 0; j < 2; j++) {
      clang_analyzer_eval(j < 2); // expected-warning {{TRUE}}
    }
    clang_analyzer_eval(j >= 2); // expected-warning {{TRUE}}
  }
  clang_analyzer_eval(i >= 10); // expected-warning {{TRUE}}
}

void nested2() {
  int i = 0, j = 0;
  for (i = 0; i < 2; i++) {
    clang_analyzer_eval(i < 2); // expected-warning {{TRUE}}
    for (j = 0; j < 10; j++) {
      clang_analyzer_eval(j < 10); // expected-warning {{TRUE}}
    }
    clang_analyzer_eval(j >= 10); // expected-warning {{TRUE}}
  }
  clang_analyzer_eval(i >= 2); // expected-warning {{TRUE}}
}
```


http://reviews.llvm.org/D12358



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

Reply via email to