https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89428
Bug ID: 89428 Summary: missing -Wstringop-overflow on a PHI with variable offset 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: --- GCC diagnoses the 1-byte overflow in the call to memset in f() but fails to diagnose the much bigger overflow in g(). The problem is the PHI that the compute_objsize() function doesn't handle. $ cat t.c && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout t.c char a[7]; void f (__SIZE_TYPE__ i) { if (i < 1 || 2 < i) i = 1; __builtin_memset (a + i, 0, 7); // warning (good) } void g (__SIZE_TYPE__ i) { if (2 < i) i = 0; __builtin_memset (a + i, 0, 99); // missing warning (bug) } ;; Function f (f, funcdef_no=0, decl_uid=1907, cgraph_uid=1, symbol_order=1) Removing basic block 3 f (long unsigned int i) { long unsigned int _1; void * _2; <bb 2> [local count: 1073741824]: _1 = i_4(D) + 18446744073709551615; if (_1 > 1) goto <bb 3>; [59.00%] else goto <bb 4>; [41.00%] <bb 3> [local count: 633507680]: <bb 4> [local count: 1073741824]: # i_3 = PHI <i_4(D)(2), 1(3)> _2 = &a + i_3; __builtin_memset (_2, 0, 7); [tail call] return; } t.c: In function ‘f’: t.c:7:3: warning: ‘__builtin_memset’ writing 7 bytes into a region of size 6 overflows the destination [-Wstringop-overflow=] 7 | __builtin_memset (a + i, 0, 7); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; Function g (g, funcdef_no=1, decl_uid=1910, cgraph_uid=2, symbol_order=2) Removing basic block 5 g (long unsigned int i) { char[7] * _6; char[7] * prephitmp_7; <bb 2> [local count: 1073741824]: if (i_3(D) > 2) goto <bb 4>; [50.00%] else goto <bb 3>; [50.00%] <bb 3> [local count: 536870912]: _6 = &a + i_3(D); <bb 4> [local count: 1073741824]: # prephitmp_7 = PHI <_6(3), &a(2)> __builtin_memset (prephitmp_7, 0, 99); [tail call] return; }