Closed 0-0x41 closed 1 year ago
I got a false positive error when compiling the following program with gcc(trunk) -fanalyzer -O2
in https://godbolt.org/z/jrxKfKEzG. Here is the result of its analysis, please take a look, thanks a lot.
#include "stdio.h"
int main()
{
int *l[2];
int **m = l;
for (int e = 0; e < 2; e++)
l[e] = (int *)42;
__analyzer_eval(0 == *m);
(*m == 0) && (__analyzer_eval(0 == *m), **m = 1);
}
<source>: In function 'main':
<source>:8:5: warning: UNKNOWN
8 | __analyzer_eval(0 == *m);
| ^~~~~~~~~~~~~~~~~~~~~~~~
<source>:9:19: warning: UNKNOWN
9 | (*m == 0) && (__analyzer_eval(0 == *m), **m = 1);
| ^~~~~~~~~~~~~~~~~~~~~~~~
<source>:9:49: warning: dereference of NULL '0' [CWE-476] [-Wanalyzer-null-dereference]
9 | (*m == 0) && (__analyzer_eval(0 == *m), **m = 1);
| ~~~~^~~
'main': events 1-5
|
| 6 | for (int e = 0; e < 2; e++)
| | ~~^~~
| | |
| | (1) following 'true' branch (when 'e != 2')...
| 7 | l[e] = (int *)42;
| | ~
| | |
| | (2) ...to here
| 8 | __analyzer_eval(0 == *m);
| 9 | (*m == 0) && (__analyzer_eval(0 == *m), **m = 1);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | | |
| | | | (5) dereference of NULL '0'
| | | (4) ...to here
| | (3) following 'true' branch...
In this case, the result of *m == 0
is FALSE, and the statement after &&
is unreachable code, which probably should not generate an NPD warning. If the initialization is done while the pointer array l
is defined, the NPD warning will not be generated (like this, https://godbolt.org/z/5hPhj1M8q) . __analyzer_eval(0 == *m)
on line 8 results in FALSE, not UNKNOWN, and __analyzer_eval(0 == *m)
on line 9 has no output (unreachable code). I think this may be a combination problem about modeling pointer arrays and initializing them under a for loop.
Still for this case, its __analyzer_eval(0 == *m)
at -O0, line 8 and line 9 have the same result as -O2 without generating the NPD warning.
Also, I found a little bit of a problem, please take a look. In this case (https://godbolt.org/z/Mh6acd66v), the result of __analyzer_eval(*m)
is UNKNOWN, yet the result of __analyzer_eval(0 == *m)
with __analyzer_eval(*m == 0)
is FALSE.
The difference between O0 and O2 is that O0 knows "m_16 == &n" while O2 does not know.
However, GSA does not know what is in the array n
and enters the true branch of "if (*m == 0)", which should be fixed.
CSA does a better job.
duplicate of issue https://github.com/Geoffrey1014/SA_Bugs/issues/16
date: 2022-12-12 commit: 8c8ca873216387bc26046615c806b96f0345ff9d args: -O2 -fanalyzer test:
report: fix: original: