NoQ added a comment.

Thank you for working on this! The overall approach is good. Because alpha 
checkers are disabled by default, false positives can be addressed later in 
subsequent commits.



================
Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:2
+// InfiniteRecursionChecker.cpp - Test if function is infinitely
+// recursive--*--//
+//
----------------
Accidental line break :o


================
Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:21
+
+REGISTER_SET_WITH_PROGRAMSTATE(DirtyStackFrames, const 
clang::StackFrameContext *)
+
----------------
k-wisniewski wrote:
> a.sidorin wrote:
> > The idea of "dirty stack frames" deserves some explanation. As I 
> > understand, it describes function calls where some values may change 
> > unexpectedly and we cannot consider this calls later. Am I understanding 
> > correctly?
> Yes! Right now it considers frame as "dirty" when there was any kind of 
> region change in this frame or in any function that was called from it. As 
> you see below, it then stops the search down the stack once it encounter such 
> a "dirty" frame, because it can no longer be sure that conditions upon which 
> the recursive call depends on did not change in an unpredictable way. It's 
> obviously too broad a definition and in the next iterations I'll try to 
> narrow it down to variables that affect whether the recursive call happens or 
> not. I also consider looking at //the way // it changes to determine if it's 
> meaningful or not.
I think this deserves commenting, at least the very mechanism of how a stack 
frame is considered dirty (if it is present in the set, or if a parent is 
present in the set, or something else, and why is the chosen method somehow 
correct).


================
Comment at: lib/StaticAnalyzer/Checkers/RecursionChecker.cpp:145
+    BT.reset(
+        new BugType(this, "Infinite recursion detected", "RecursionChecker"));
+
----------------
I think one of the builtin bugtypes should be used, such as `LogicError`. In 
any case, both of these should be human-friendly (they appear eg. in scan-view).


================
Comment at: test/Analysis/recursion.cpp:27
+
+void f2();
+void f3();
----------------
k-wisniewski wrote:
> a.sidorin wrote:
> > I'd like to see some more informative function names: for me, it is hard to 
> > distinguish between f1-7 here :) It is also hard to determine the function 
> > where test starts.
> The convention I know is that the bottom-most one gets considered first, but 
> I may add some explicitly marked entry points for the sake of consistency and 
> to make it easier to reason about. 
There's a way to hard-check this through `FileCheck` + 
`-analyzer-display-progress` (see `inlining/analysis-order.c`). Might be an 
overkill, but on the other hand may actually improve readability of the test 
quite a bit.


================
Comment at: test/Analysis/recursion.cpp:37
+void f2() {
+    SampleGlobalVariable = 1;
+    f3();
----------------
This should eventually warn. Even though the variable is accessed, it's not 
really changed :)

I'd suggest something like:
```
++SampleGlobalVariable;
if (SampleGlobalVariable < 100)
  f3();
```
It'd make sure that the test is "correct" (it's obvious to the reader that this 
is a false positive we'd never want to warn about). But you could also keep the 
original test with a FIXME remark ("we should eventually warn about this").

I also think that this group of tests deserves to have the following test:
```
bool bar(); // no definition!
void foo() {
  if (bar()) { // may change the global state
    foo(); // no-warning
  }
}
```
This test case should magically work because calling `bar()` will change the 
"global memory space" region (invalidate all globals).


https://reviews.llvm.org/D26589



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

Reply via email to