https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98109
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed| |2020-12-03 Ever confirmed|0 |1 Keywords| |diagnostic CC| |msebor at gcc dot gnu.org Blocks| |95507 Status|UNCONFIRMED |NEW --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- The warings are caused by the null tests inserted by the sanitizer that jump threading turns into calls with constant nulls. See below. Adding attribute nonnull also to swap_1000 avoids both the warnings and the sanitization. This is a known problem with the sanitizer and the late warnings and there probably is a report like this one in Bugzilla somewhere. I suppose the warning code could look for calls __builtin___ubsan_handle_nonnull_arg (and similar) preceding the statement it's about to diagnose and avoid triggering if it's found. Until something like this is implemented the guidance is to live with these warnings when using the sanitizer or suppress them by -Wno-xxx. $ gcc -O2 -S -Wall -fsanitize=undefined -fdump-tree-ubsan=/dev/stdout -fdump-tree-dom2=/dev/stdout pr98109.c ;; Function swap_1000 (swap_1000, funcdef_no=0, decl_uid=2388, cgraph_uid=1, symbol_order=0) Introduced new external node (__builtin___ubsan_handle_nonnull_arg/3). Symbols to be put in SSA form { D.2392 } Incremental SSA update started at block: 0 Number of blocks in CFG: 15 Number of blocks to update: 14 ( 93%) void swap_1000 (char * elem1, char * elem2, size_t element_size) { char buffer[1000]; <bb 2> : if (&buffer == 0B) goto <bb 4>; [0.05%] else goto <bb 3>; [99.95%] <bb 4> : __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data0); <bb 3> : if (elem1_2(D) == 0B) goto <bb 6>; [0.05%] else goto <bb 5>; [99.95%] <bb 6> : __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data1); <bb 5> : my_memcpy (&buffer, elem1_2(D), 1000); if (elem1_2(D) == 0B) goto <bb 8>; [0.05%] else goto <bb 7>; [99.95%] <bb 8> : __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data2); <bb 7> : if (elem2_4(D) == 0B) goto <bb 10>; [0.05%] else goto <bb 9>; [99.95%] <bb 10> : __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data3); <bb 9> : my_memcpy (elem1_2(D), elem2_4(D), 1000); if (elem2_4(D) == 0B) goto <bb 12>; [0.05%] else goto <bb 11>; [99.95%] <bb 12> : __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data4); <bb 11> : if (&buffer == 0B) goto <bb 14>; [0.05%] else goto <bb 13>; [99.95%] <bb 14> : __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data5); <bb 13> : my_memcpy (elem2_4(D), &buffer, 1000); buffer ={v} {CLOBBER}; return; } ;; Function swap_1000 (swap_1000, funcdef_no=0, decl_uid=2388, cgraph_uid=1, symbol_order=0) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 3 4 5 6 7 8 ;; 2 succs { 8 3 } ;; 3 succs { 4 } ;; 4 succs { 7 5 } ;; 5 succs { 6 } ;; 6 succs { 1 } ;; 7 succs { 6 } ;; 8 succs { 4 } void swap_1000 (char * elem1, char * elem2, size_t element_size) { char buffer[1000]; <bb 2> [local count: 1073741824]: if (elem1_2(D) == 0B) goto <bb 3>; [0.00%] else goto <bb 8>; [100.00%] <bb 3> [count: 0]: __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data1); my_memcpy (&buffer, 0B, 1000); __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data2); <bb 4> [local count: 1073741824]: if (elem2_4(D) == 0B) goto <bb 5>; [0.00%] else goto <bb 7>; [100.00%] <bb 5> [count: 0]: __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data3); my_memcpy (elem1_2(D), 0B, 1000); __builtin___ubsan_handle_nonnull_arg (&*.Lubsan_data4); <bb 6> [local count: 1073741824]: my_memcpy (elem2_4(D), &buffer, 1000); buffer ={v} {CLOBBER}; return; <bb 7> [local count: 1073741824]: my_memcpy (elem1_2(D), elem2_4(D), 1000); goto <bb 6>; [100.00%] <bb 8> [local count: 1073741824]: my_memcpy (&buffer, elem1_2(D), 1000); goto <bb 4>; [100.00%] } pr98109.c: In function ‘swap_1000’: pr98109.c:11:5: warning: argument 2 is null but the corresponding size argument 3 value is 1000 [-Wnonnull] 11 | my_memcpy(buffer, elem1, 1000); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr98109.c:3:7: note: in a call to function ‘my_memcpy’ declared with attribute ‘access (read_only, 2, 3)’ 3 | void *my_memcpy(void *destination, const void *source, size_t size) | ^~~~~~~~~ pr98109.c:12:5: warning: argument 2 is null but the corresponding size argument 3 value is 1000 [-Wnonnull] 12 | my_memcpy(elem1, elem2, 1000); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr98109.c:3:7: note: in a call to function ‘my_memcpy’ declared with attribute ‘access (read_only, 2, 3)’ 3 | void *my_memcpy(void *destination, const void *source, size_t size) | ^~~~~~~~~ Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95507 [Bug 95507] [meta-bug] bogus/missing -Wnonnull