https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108646
--- Comment #3 from Jonny Grant <jg at jguk dot org> --- (In reply to Jonathan Wakely from comment #2) > It already does detect it: > > n.c: In function ‘test’: > n.c:6:2: warning: argument 1 null where non-null expected [-Wnonnull] > 6 | mem2(dest); > | ^~~~~~~~~~ > n.c:2:8: note: in a call to function ‘mem2’ declared ‘nonnull’ > 2 | void * mem2(void *dest) __attribute__((nonnull)); > | ^~~~ > > You need to enable optimization, otherwise there is no data flow analysis. > > Without optimization, it detects it with -fanalyzer > > n.c: In function ‘void test()’: > n.c:6:6: warning: use of NULL ‘dest’ where non-null expected [CWE-476] > [-Wanalyzer-null-argument] > 6 | mem2(dest); > | ~~~~^~~~~~ > ‘void test()’: events 1-2 > | > | 5 | char *dest = NULL; > | | ^~~~ > | | | > | | (1) ‘dest’ is NULL > | 6 | mem2(dest); > | | ~~~~~~~~~~ > | | | > | | (2) argument 1 (‘dest’) NULL where non-null expected > | > n.c:2:8: note: argument 1 of ‘void* mem2(void*)’ must be non-null > 2 | void * mem2(void *dest) __attribute__((nonnull)); > | ^~~~ > > > And it's also detected at runtime using -fsanitize=undefined: > > n.c:6:6: runtime error: null pointer passed as argument 1, which is declared > to never be null That's great it works with optimization, I should remember to always do that.(In reply to Jonathan Wakely from comment #2) > It already does detect it: > > n.c: In function ‘test’: > n.c:6:2: warning: argument 1 null where non-null expected [-Wnonnull] > 6 | mem2(dest); > | ^~~~~~~~~~ > n.c:2:8: note: in a call to function ‘mem2’ declared ‘nonnull’ > 2 | void * mem2(void *dest) __attribute__((nonnull)); > | ^~~~ > > You need to enable optimization, otherwise there is no data flow analysis. > > Without optimization, it detects it with -fanalyzer > > n.c: In function ‘void test()’: > n.c:6:6: warning: use of NULL ‘dest’ where non-null expected [CWE-476] > [-Wanalyzer-null-argument] > 6 | mem2(dest); > | ~~~~^~~~~~ > ‘void test()’: events 1-2 > | > | 5 | char *dest = NULL; > | | ^~~~ > | | | > | | (1) ‘dest’ is NULL > | 6 | mem2(dest); > | | ~~~~~~~~~~ > | | | > | | (2) argument 1 (‘dest’) NULL where non-null expected > | > n.c:2:8: note: argument 1 of ‘void* mem2(void*)’ must be non-null > 2 | void * mem2(void *dest) __attribute__((nonnull)); > | ^~~~ > > > And it's also detected at runtime using -fsanitize=undefined: > > n.c:6:6: runtime error: null pointer passed as argument 1, which is declared > to never be null That's great. I should have remembered to add -O2 Is it worth -Wnonnull emitting a warning message that it needs optimization to get the needed data flow analysis?