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]);