https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91848
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- GCC 10.0 diagnoses all but one instance of the buffer overflow, namely the one in arr_var. (It issues duplicate warnings which might be something to look into.) $ gcc -O2 -S -Wall pr91848.c pr91848.c: In function ‘arr_cst’: pr91848.c:12:3: warning: ‘strcpy’ writing 5 bytes into a region of size 3 [-Wstringop-overflow=] 12 | strcpy (q->a, a + sizeof a - 4 - 1); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr91848.c:3:17: note: at offset 0 to object ‘a’ with size 3 declared here 3 | struct A { char a[3]; int i; }; | ^ pr91848.c:12:3: warning: ‘strcpy’ offset [91, 92] from the object at ‘b’ is out of the bounds of referenced subobject ‘a’ with type ‘char[3]’ at offset 88 [-Warray-bounds] 12 | strcpy (q->a, a + sizeof a - 4 - 1); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr91848.c:3:17: note: subobject ‘a’ declared here 3 | struct A { char a[3]; int i; }; | ^ pr91848.c: In function ‘ptr_cst’: pr91848.c:19:3: warning: ‘strcpy’ writing 5 bytes into a region of size 3 [-Wstringop-overflow=] 19 | strcpy (q->a, a + sizeof a - 4 - 1); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr91848.c:3:17: note: at offset 0 to object ‘a’ with size 3 declared here 3 | struct A { char a[3]; int i; }; | ^ pr91848.c:19:3: warning: ‘strcpy’ offset [91, 92] from the object at ‘p’ is out of the bounds of referenced subobject ‘a’ with type ‘char[3]’ at offset 88 [-Warray-bounds] 19 | strcpy (q->a, a + sizeof a - 4 - 1); // warning (good) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr91848.c:3:17: note: subobject ‘a’ declared here 3 | struct A { char a[3]; int i; }; | ^ pr91848.c: In function ‘ptr_var’: pr91848.c:33:3: warning: ‘strcpy’ writing 5 bytes into a region of size 3 [-Wstringop-overflow=] 33 | strcpy (q->a, a + sizeof a - 4 - 1); // missing warning | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pr91848.c:3:17: note: at offset 0 to object ‘a’ with size 3 declared here 3 | struct A { char a[3]; int i; }; | ^ The IL for arr_var where the overflow is not diagnosed looks like so: arr_var (int i) { const char a[11]; char[3] * _1; sizetype _7; sizetype _8; sizetype _9; <bb 2> [local count: 1073741824]: a = "0123456789"; _7 = (sizetype) i_2(D); _8 = _7 * 12; _9 = _8 + 4; _1 = &b + _9; strcpy (_1, &MEM <const char[11]> [(void *)&a + 6B]); a ={v} {CLOBBER}; return; } so the detail that the store is to the member of the array b rather than to b itself is lost. This appears to be caused by the laddress pass. Until then the IL still shows: <bb 2> [local count: 1073741824]: a = "0123456789"; _1 = &MEM <struct B[<unknown>]> [(struct A *)&b][i_2(D)].a.a; strcpy (_1, &MEM <const char[11]> [(void *)&a + 6B]);