https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101688
Martin Sebor changed:
What|Removed |Added
Ever confirmed|0 |1
Last reconfirmed||2021-08-03
Status|UNCONFIRMED |NEW
Keywords||diagnostic
--- Comment #2 from Martin Sebor ---
I can confirm the unexpected warnings but the reason for them isn't that
they're somehow confused. They're correct for the emitted IL.
Here's a small example:
$ cat pr101688.C && gcc -O2 -S -Wall -m32 pr101688.C
char *p, *q;
void f (int n)
{
if (n < 0)
n = 0;
p = (char*)new int[n];
*p = 0;
q = (char*)new int[n + 1];
*q = 0;
}
pr101688.C: In function ‘void f(int)’:
pr101688.C:9:6: warning: writing 1 byte into a region of size 0
[-Wstringop-overflow=]
9 | *p = 0;
| ~~~^~~
pr101688.C:8:23: note: destination object of size 0 allocated by ‘operator new
[]’
8 | p = (char*)new int[n];
| ^
The IL the warning is issued for is the following:
[local count: 1073741824]:
if (n_3(D) < 0)
goto ; [25.50%]
...
[local count: 273804168]:
_29 = operator new [] (0); <<< zero-sized allocation
p = _29;
MEM[(char *)_29] = 0; <<< -Wstringop-overflow
goto ; [100.00%]
The invalid code in bb 8 is first seen in the vrp1 dump:
[local count: 1073741824]:
if (n_3(D) < 0)
goto ; [25.50%]
...
[local count: 273804168]:
# n_25 = PHI <0(2)>
# n.1_26 = PHI <0(2)>
iftmp.0_27 = n.1_26 * 4;
_29 = operator new [] (iftmp.0_27);
p = _29;
MEM[(char *)_29] = 0;
When i == 0, the first allocation creates a zero-sized object which then
results in an out-of-bounds store. If this were real code (as opposed to a
test) I'd say the code is unsafe and warning for it is justified. What's
unhelpful here is that the warning that ends up issued doesn't make the problem
clear.