https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108028

            Bug ID: 108028
           Summary: --Wanalyzer-null-dereference false posiative with *q =
                    1
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: mengli.ming at outlook dot com
  Target Milestone: ---

I got a false positive error when compiling the following program with
gcc(trunk) -fanalyzer -O2 in https://godbolt.org/z/W37MzrPqd. The
`__analyzer_eval()` statement is added at some suitable places in the code in
order to keep track of the information already available to the analyzer at
some point in the static analysis of the program. After that, I found that
under -O0, for this program (https://godbolt.org/z/Y1GMEMaG9),
`__analyzer_eval(p && (0 == q))`, `__analyzer_eval(p)`, `__analyzer_eval(0 ==
q)` give the same result at the same program point as -O2 without generating
the NPD warning. The following is the result of the analysis obtained using
-O2, please take a look, thank you.

```
#include "stdio.h"
int f(int, int *);

int f(int p, int *q)
{
    __analyzer_eval(p && (0 == q));
    if (p && (0 == q))
    {
        __analyzer_eval(p && (0 == q));
        __analyzer_eval(p);
        __analyzer_eval(0 == p);
        __analyzer_eval(q);
        __analyzer_eval(0 == q);
        *q = 1;
    }
    printf("NPD_FLAG\n");
}

int main()
{
    int a = 0;
    int *b = (void*)0;
    f(a, b);
}

```

```
<source>: In function 'f':
<source>:6:5: warning: FALSE
    6 |     __analyzer_eval(p && (0 == q));
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:6:5: warning: UNKNOWN
<source>:9:9: warning: TRUE
    9 |         __analyzer_eval(p && (0 == q));
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:10:9: warning: TRUE
   10 |         __analyzer_eval(p);
      |         ^~~~~~~~~~~~~~~~~~
<source>:11:9: warning: FALSE
   11 |         __analyzer_eval(0 == p);
      |         ^~~~~~~~~~~~~~~~~~~~~~~
<source>:12:9: warning: UNKNOWN
   12 |         __analyzer_eval(q);
      |         ^~~~~~~~~~~~~~~~~~
<source>:13:9: warning: TRUE
   13 |         __analyzer_eval(0 == q);
      |         ^~~~~~~~~~~~~~~~~~~~~~~
<source>:14:12: warning: dereference of NULL '0' [CWE-476]
[-Wanalyzer-null-dereference]
   14 |         *q = 1;
      |         ~~~^~~
  'f': events 1-3
    |
    |    7 |     if (p && (0 == q))
    |      |        ^
    |      |        |
    |      |        (1) following 'true' branch...
    |    8 |     {
    |    9 |         __analyzer_eval(p && (0 == q));
    |      |         ~~~~~~~~~~~~~~~
    |      |         |
    |      |         (2) ...to here
    |......
    |   14 |         *q = 1;
    |      |         ~~~~~~
    |      |            |
    |      |            (3) dereference of NULL '0'

```

In the analysis under -O2 above, lines 12 and 13 are somewhat contradictory, as
`__analyzer_eval(q)` results in UNKNOWN while `__analyzer_eval(0 == q)` results
in TRUE.

Reply via email to