Open 0-0x41 opened 1 year ago
I got a false negative error when compiling the following program with gcc(trunk) -fanalyzer -O0
in https://godbolt.org/z/65bzcYr19. After changing int e = 1
to int e = 0
, the NPD appears.
By adding the __analyzer_eval()
at the appropriate place in the code, I found that after iterating through the for loop once and exiting the loop body, the result for 0 == e
is unknown. However, as mentioned above, after changing int e = 1
to int e = 0
, the result for 0 == e
is true.
Here is the result of the program, please take a look, thank you.
#include <stdio.h>
int main() {
int e = 1;
int *f;
for (int i = 0; i < 1; i++) {
e = 0;
__analyzer_eval(0 == e);
}
__analyzer_eval(0 == e);
f = e;
__analyzer_eval(0 == f);
*f = 1;
return 0;
}
<source>: In function 'main':
<source>:8:5: warning: TRUE
8 | __analyzer_eval(0 == e);
| ^~~~~~~~~~~~~~~~~~~~~~~
<source>:8:5: warning: TRUE
<source>:11:3: warning: UNKNOWN
11 | __analyzer_eval(0 == e);
| ^~~~~~~~~~~~~~~~~~~~~~~
<source>:14:3: warning: UNKNOWN
14 | __analyzer_eval(0 == f);
| ^~~~~~~~~~~~~~~~~~~~~~~
GCC can only infer the value of e when e is assigned to the same value in lines 3 and 7. It would be related to the challenge of finding the invariant for the loop.
This false negative is kind of interesting, but we should report other more convincing issues first in my opinion.
I got a false negative error when compiling the following program with gcc(trunk) -fanalyzer -O0
. It is obvious that *f = 1;
( at line 15 ) will lead to a NPD error, but gcc static analyzer can not find it.
And i found that analyzer did not know __analyzer_eval(0 == e);
and __analyzer_eval(0 == f);
were both true.
In addition, i observed that analyzer seemed to enter the loop for two times (it evaluated __analyzer_eval(0 == e);
for two times). I think this may hint at something wrong.
https://godbolt.org/z/EjYqhsrWe
In addition, CSA does a better job : https://godbolt.org/z/54n5so49P
#include <stdio.h>
extern void __analyzer_eval (int);
int main() {
int e = 1;
int *f;
for (int i = 0; i < 1; i++) {
e = 0;
__analyzer_eval(0 == e);
}
__analyzer_eval(0 == e);
f = (int*) e;
__analyzer_eval(0 == f);
*f = 1;
return 0;
}
Output:
<source>: In function 'main':
<source>:12:7: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
12 | f = (int*) e;
| ^
<source>:9:5: warning: TRUE
9 | __analyzer_eval(0 == e);
| ^~~~~~~~~~~~~~~~~~~~~~~
<source>:9:5: warning: TRUE
<source>:11:3: warning: UNKNOWN
11 | __analyzer_eval(0 == e);
| ^~~~~~~~~~~~~~~~~~~~~~~
<source>:14:3: warning: UNKNOWN
14 | __analyzer_eval(0 == f);
| ^~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 0
However, if I change int e = 1
to int e = 0
or to int * e
, analyzer can find the NPD error correctly. So maybe the casting to pointer from integer leads to the problem.
CSA not FN: https://godbolt.org/z/W47Tx5rr3
date: 2022-11-22 commit: 8c8ca873216387bc26046615c806b96f0345ff9d args: -O0 -fanalyzer test:
report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108428 fix: original: