Open Geoffrey1014 opened 1 year ago
I encountered a false positive when compiling the following MCVE program with gcc (trunk) with -fanalyzer -O0 in https://godbolt.org/z/qnM58d8v5
#include <stdio.h>
void a( int *d , int* e) {
printf("NPD_FLAG\n");
e == 0 && (d = 0) != *e; // *f result in npd
}
int main() {
int i =5;
a(0 ,&i);
}
results in:
<source>: In function 'a':
<source>:4:21: warning: comparison between pointer and integer
4 | e == 0 && (d = 0) != *e; // *e result in npd
| ^~
<source>:4:24: warning: dereference of NULL 'e' [CWE-476] [-Wanalyzer-null-dereference]
4 | e == 0 && (d = 0) != *e; // *e result in npd
| ^~
'a': events 1-4
|
| 4 | e == 0 && (d = 0) != *e; // *e result in npd
| | ~~~~~~~^~~~~~~~~~~~~~~~
| | | | |
| | | | (4) dereference of NULL 'e'
| | | (2) ...to here
| | | (3) 'e' is NULL
| | (1) following 'true' branch (when 'e' is NULL)...
|
Compiler returned: 0
Gcc static analyzer reports " dereference of NULL 'e' " at line 4, which is a false positive, while it gives wrong path note "(3) 'e' is NULL".
If I change int *d to int d as the following one, the NPD warning disappears, while d is unrelated to e.
#include <stdio.h>
void a( int d , int* e) {
printf("NPD_FLAG\n");
e == 0 && (d = 0) != *e; // *f result in npd
}
int main() {
int i =5;
a(0 ,&i);
}
If I change the original code to the following one by removing variable d, the NPD warning also disappears.
#include <stdio.h>
void a(int* e) {
printf("NPD_FLAG\n");
e == 0 && *e; // *e result in npd
}
int main() {
int i =5;
a(&i);
}
The origianl one is essentially same as this one.
I got a false positive warning when compiling the following program with gcc(trunk) -fanalyzer -O0
in https://godbolt.org/z/YbeGcc5cd. After deleting int *d = 0;
, the NPD disappears. I think it is ok for gcc to emit this FP warning, but deleting the unrelated code int *d = 0;
should not affect the result. And the path note (3) 'e' is NULL
is wrong, this may suggest some problems.
I have tried this with gcc 12, gcc 11, and gcc 10, and all of them have this phenomenon.
Program:
#include <stdio.h>
void a( int* e) {
printf("NPD_FLAG\n");
if(e == 0){
int *d = 0;
*e = 1;
}
}
int main() {
int i =5;
a(&i);
}
Warning:
<source>: In function 'a':
<source>:6:12: warning: dereference of NULL 'e' [CWE-476] [-Wanalyzer-null-dereference]
6 | *e = 1;
| ~~~^~~
'a': events 1-4
|
| 4 | if(e == 0){
| | ^
| | |
| | (1) following 'true' branch (when 'e' is NULL)...
| 5 | int *d = 0;
| | ~
| | |
| | (2) ...to here
| | (3) 'e' is NULL
| 6 | *e = 1;
| | ~~~~~~
| | |
| | (4) dereference of NULL 'e'
|
Thanks for your explanation. It helps a lot.
It's analyzing "a" twice: as called by main, and as a standalone function.
I am wondering if is there any option for gcc to specify main
as the only top-level function, i.e., do not let a
be analyzed standalone.
deleting the unrelated code
int *d = 0;
should not affect the result (but does)
I am also curious about why deleting int *d = 0;
affects the analyzing results. Do you have thoughts on this?
CSA not FP: https://godbolt.org/z/haq6TrsxG.
date: 2022-11-15 commit: 225f9c8805fb1ba68a877383095f38a9563526ee args: -fanalyzer -O0 test:
report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107733 fix: original: