https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92110
Bug ID: 92110 Summary: too many -Warray-bounds warnings for a loop buffer overflow Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- As mentioned in bug 92016, when GCC unrolls a loop that writes past the end of a buffer a separate instance of -Warray-bounds is issued for each iteration of the loop that writes past the end of the destination. This can be seen in output for the test case below. Likewise for -Wstringop-overflow when -Warray-bounds is disabled. It would make the diagnostic output much less cluttered (and less overwhelming) if just a single warning was issued instead that descried the full extent of the buffer overflow (i.e., its size and offset from the beginning of the buffer). $ cat c.c && gcc -S -O2 -Wall -Wextra -fdump-tree-strlen=/dev/stdout -fdump-tree-optimized=/dev/stdout c.c static void f (char *p, unsigned n) { while (n--) *p++ = 0; } void g (void*); void h (void) { char a[4]; f (a, 8); g (a); } c.c: In function ‘h’: c.c:4:10: warning: array subscript 4 is outside array bounds of ‘char[4]’ [-Warray-bounds] 4 | *p++ = 0; | ~~~~~^~~ c.c:11:8: note: while referencing ‘a’ 11 | char a[4]; | ^ c.c:4:10: warning: array subscript 5 is outside array bounds of ‘char[4]’ [-Warray-bounds] 4 | *p++ = 0; | ~~~~~^~~ c.c:11:8: note: while referencing ‘a’ 11 | char a[4]; | ^ c.c:4:10: warning: array subscript 6 is outside array bounds of ‘char[4]’ [-Warray-bounds] 4 | *p++ = 0; | ~~~~~^~~ c.c:11:8: note: while referencing ‘a’ 11 | char a[4]; | ^ c.c:4:10: warning: array subscript 7 is outside array bounds of ‘char[4]’ [-Warray-bounds] 4 | *p++ = 0; | ~~~~~^~~ c.c:11:8: note: while referencing ‘a’ 11 | char a[4]; | ^ ;; Function h (h, funcdef_no=1, decl_uid=1939, cgraph_uid=2, symbol_order=1) ;; 2 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } h () { char * p; unsigned int n; char a[4]; <bb 2> [local count: 118111601]: MEM[(char *)&a] = 0; MEM[(char *)&a + 1B] = 0; MEM[(char *)&a + 2B] = 0; MEM[(char *)&a + 3B] = 0; MEM[(char *)&a + 4B] = 0; MEM[(char *)&a + 5B] = 0; MEM[(char *)&a + 6B] = 0; MEM[(char *)&a + 7B] = 0; g (&a); a ={v} {CLOBBER}; return; } ;; Function h (h, funcdef_no=1, decl_uid=1939, cgraph_uid=2, symbol_order=1) h () { char a[4]; <bb 2> [local count: 118111601]: MEM <unsigned long> [(char *)&a] = 0; g (&a); a ={v} {CLOBBER}; return; } $ gcc -S -O2 -Wall -Wextra -Wno-array-bounds c.c static void f (char *p, unsigned n) { while (n--) *p++ = 0; } void g (void*); void h (void) { char a[4]; f (a, 8); g (a); } In function ‘f’, inlined from ‘h’ at c.c:12:3: c.c:4:10: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 4 | *p++ = 0; | ~~~~~^~~ c.c: In function ‘h’: c.c:11:8: note: destination object declared here 11 | char a[4]; | ^ In function ‘f’, inlined from ‘h’ at c.c:12:3: c.c:4:10: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 4 | *p++ = 0; | ~~~~~^~~ c.c: In function ‘h’: c.c:11:8: note: destination object declared here 11 | char a[4]; | ^ In function ‘f’, inlined from ‘h’ at c.c:12:3: c.c:4:10: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 4 | *p++ = 0; | ~~~~~^~~ c.c: In function ‘h’: c.c:11:8: note: destination object declared here 11 | char a[4]; | ^ In function ‘f’, inlined from ‘h’ at c.c:12:3: c.c:4:10: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] 4 | *p++ = 0; | ~~~~~^~~ c.c: In function ‘h’: c.c:11:8: note: destination object declared here 11 | char a[4]; | ^