Open llvmbot opened 15 years ago
mentioned in issue llvm/llvm-bugzilla-archive#5976
mentioned in issue llvm/llvm-bugzilla-archive#5780
The issue still reproduces with recent builds.
$ cat test.c
void foo(int i) { if (i != 0) { if (-i == 0) { (void) strlen(NULL); } } } $ clang-tidy-9 test.c Error while trying to load a compilation database: Could not auto-detect compilation database for file "test.c" No compilation database found in /tmp or any parent directory fixed-compilation-database: Error while opening fixed database: No such file or directory json-compilation-database: Error while opening JSON database: No such file or directory Running without flags. 2 warnings generated. /tmp/test.c:6:20: warning: Null pointer passed as an argument to a 'nonnull' parameter [clang-analyzer-core.NonNullParamChecker] (void) strlen(NULL); ^ /tmp/test.c:4:9: note: Assuming 'i' is not equal to 0 if (i != 0) { ^ /tmp/test.c:4:5: note: Taking true branch if (i != 0) { ^ /tmp/test.c:5:9: note: Taking true branch if (-i == 0) { ^ /tmp/test.c:6:20: note: Null pointer passed as an argument to a 'nonnull' parameter (void) strlen(NULL); ^ /tmp/test.c:6:31: warning: null passed to a callee that requires a non-null argument [clang-diagnostic-nonnull] (void) strlen(NULL); ^
Obviously, -i == 0
is false assuming i is not equal to 0
Reopening because the static analyzer still does not track linear constraints.
The attached example (reproduced below) no longer shows a false positive in more recent clangs because the analyzer changed its heuristics about when to analyze functions at the top level, without context.
With these changed heuristics, the analyzer doesn't analyze msort() as a top-level function but rather only in context (inlining) for the three calls in main(). If you were to comment out main, the analysis would analyze msort() at the top-level (making no assumptions about len) and show the false positive again: "Dereference of null pointer (loaded from variable 'q')".
static int dummy = 42;
void msort(int len) { int p, q = NULL; int half, n;
if (len <= 1) return;
half = len >> 1; p = &dummy; for (n = half; --n >= 0; ) { q = p; } printf("%d\n", *q); // <-- False positive here.
}
int main(int argc, char **argv) { msort(1); msort(2); msort(3);
return (0); }
The bug is not reproducible anymore using clang 3.7/3.8.
This is related to PR 2695.
The analyzer does track a range constraint for 'len'. What is lost is the linear constraint that 'half = len / 2'.
assigned to @tkremenek
Extended Description
Hi, I'm not sure ccc-analyzer is already smart enough to avoid these false positives, but there is a pretty small function in FreeBSD's sh(1) where it fails. The real example can be seen at: https://www.spoerlein.net/scan-build/2009-07-04-1/report-STEwrs.html#EndPath
I'll attach a minimal test case showing the problem. The loop condition in that example can never be false, but is flagged as such.