Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

track linear constraints #5064

Open Quuxplusone opened 15 years ago

Quuxplusone commented 15 years ago
Bugzilla Link PR4550
Status REOPENED
Importance P normal
Reported by uspoerlein@gmail.com
Reported on 2009-07-13 13:10:47 -0700
Last modified on 2019-01-27 10:15:10 -0800
Version trunk
Hardware PC FreeBSD
CC dcoughlin@apple.com, ignat.loskutov@gmail.com, kbobyrev.opensource@gmail.com, kremenek@apple.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments clang-expand.c (347 bytes, text/plain)
Blocks PR5780, PR5976
Blocked by
See also

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.

Quuxplusone commented 15 years ago

Attached clang-expand.c (347 bytes, text/plain): snipped from FreeBSD sh(1)'s expand.c

Quuxplusone commented 15 years ago

The analyzer does track a range constraint for 'len'. What is lost is the linear constraint that 'half = len / 2'.

Quuxplusone commented 15 years ago

This is related to PR 2695.

Quuxplusone commented 8 years ago

The bug is not reproducible anymore using clang 3.7/3.8.

Quuxplusone commented 8 years ago
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')".

#include <stdlib.h>
#include <stdio.h>

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);
}
Quuxplusone commented 5 years ago

The issue still reproduces with recent builds.

$ cat test.c

include

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