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.