gcc (Debian 11-20210130-1) 11.0.0 20210130 (experimental) [master revision 4d31df40899:799f8820257:2900f2f2c5fb234678eb8b76564e5994ec5970b9]
gcc -fanalyzer for the sample code below gives false positive results. If I remove field ref from struct marker, no problem is reported. Best regards Heinrich test.c ====== #include <stdlib.h> struct marker { struct marker *next; void *ref; }; struct data { struct marker *marker; }; void data_free(struct data d) { struct marker *nm, *m; m = d.marker; while (m) { nm = m->next; free(m->ref); free(m); m = nm; } } $ gcc test.c -fanalyzer -c test.c: In function ‘data_free’: test.c:17:20: warning: use after ‘free’ of ‘m’ [CWE-416] [-Wanalyzer-use-after-free] 17 | nm = m->next; | ~~~^~~~~~~~~ ‘data_free’: events 1-18 | | 16 | while (m) { | | ^ | | | | | (1) following ‘true’ branch (when ‘m’ is non-NULL)... | | (3) following ‘true’ branch (when ‘m’ is non-NULL)... | | (5) following ‘true’ branch (when ‘m’ is non-NULL)... | | (7) following ‘true’ branch (when ‘m’ is non-NULL)... | | (10) following ‘true’ branch (when ‘m’ is non-NULL)... | | (12) following ‘true’ branch (when ‘m’ is non-NULL)... | | (14) following ‘true’ branch (when ‘m’ is non-NULL)... | | (16) following ‘true’ branch (when ‘m’ is non-NULL)... | 17 | nm = m->next; | | ~~~~~~~~~~~~ | | | | | (2) ...to here | | (4) ...to here | | (6) ...to here | | (8) ...to here | | (11) ...to here | | (13) ...to here | | (15) ...to here | | (17) ...to here | | (18) use after ‘free’ of ‘m’; freed at (9) | 18 | free(m->ref); | 19 | free(m); | | ~~~~~~~ | | | | | (9) freed here | test.c:18:17: warning: double-‘free’ of ‘*m.ref’ [CWE-415] [-Wanalyzer-double-free] 18 | free(m->ref); | ^~~~~~~~~~~~ ‘data_free’: events 1-16 | | 16 | while (m) { | | ^ | | | | | (1) following ‘true’ branch (when ‘m’ is non-NULL)... | | (3) following ‘true’ branch (when ‘m’ is non-NULL)... | | (5) following ‘true’ branch (when ‘m’ is non-NULL)... | | (8) following ‘true’ branch (when ‘m’ is non-NULL)... | | (10) following ‘true’ branch (when ‘m’ is non-NULL)... | | (12) following ‘true’ branch (when ‘m’ is non-NULL)... | | (14) following ‘true’ branch (when ‘m’ is non-NULL)... | 17 | nm = m->next; | | ~~~~~~~~~~~~ | | | | | (2) ...to here | | (4) ...to here | | (6) ...to here | | (9) ...to here | | (11) ...to here | | (13) ...to here | | (15) ...to here | 18 | free(m->ref); | | ~~~~~~~~~~~~ | | | | | (7) first ‘free’ here | | (16) second ‘free’ here; first ‘free’ was at (7) |