[Bug regression/102513] New: False positive -Wstringop-overflow= or -Warray-bounds warning with recursive function
andreas.rheinhardt at outlook dot com
gcc-bugzilla@gcc.gnu.org
Tue Sep 28 08:40:00 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102513
Bug ID: 102513
Summary: False positive -Wstringop-overflow= or -Warray-bounds
warning with recursive function
Product: gcc
Version: 10.0
Status: UNCONFIRMED
Keywords: diagnostic
Severity: normal
Priority: P3
Component: regression
Assignee: unassigned at gcc dot gnu.org
Reporter: andreas.rheinhardt at outlook dot com
Target Milestone: ---
Created attachment 51514
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51514&action=edit
A file that produces false warnings when compiled with -O3.
extern int block2[7][256];
static int encode_block(int block2[7][256], unsigned level)
{
int best_score = 0;
for (unsigned x = 0; x < level; x++) {
int v = block2[1][x];
block2[level][x] = 0;
best_score += v * v;
}
if (level > 0 && best_score > 64) {
int score = 0;
score += encode_block(block2, level - 1);
score += encode_block(block2, level - 1);
if (score < best_score) {
best_score = score;
}
}
return best_score;
}
int foo(void)
{
return encode_block(block2, 5);
}
As is easily seen, level in the above code is always in the range 0..5 and
therefore all accesses are safe. Yet when one compiles the above with -O3 (-O2
is quiet), one receives several warnings:
../gcc_bug.c: In function 'encode_block.constprop':
../gcc_bug.c:9:26: warning: iteration 256 invokes undefined behavior
[-Waggressive-loop-optimizations]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:7:5: note: within this loop
7 | for (unsigned x = 0; x < level; x++) {
| ^~~
../gcc_bug.c:9:26: warning: iteration 256 invokes undefined behavior
[-Waggressive-loop-optimizations]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:7:5: note: within this loop
7 | for (unsigned x = 0; x < level; x++) {
| ^~~
../gcc_bug.c:9:26: warning: iteration 256 invokes undefined behavior
[-Waggressive-loop-optimizations]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:7:5: note: within this loop
7 | for (unsigned x = 0; x < level; x++) {
| ^~~
../gcc_bug.c:9:26: warning: iteration 256 invokes undefined behavior
[-Waggressive-loop-optimizations]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:7:5: note: within this loop
7 | for (unsigned x = 0; x < level; x++) {
| ^~~
../gcc_bug.c:9:26: warning: iteration 256 invokes undefined behavior
[-Waggressive-loop-optimizations]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:7:5: note: within this loop
7 | for (unsigned x = 0; x < level; x++) {
| ^~~
../gcc_bug.c:9:26: warning: iteration 256 invokes undefined behavior
[-Waggressive-loop-optimizations]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:7:5: note: within this loop
7 | for (unsigned x = 0; x < level; x++) {
| ^~~
../gcc_bug.c:9:26: warning: iteration 256 invokes undefined behavior
[-Waggressive-loop-optimizations]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:7:5: note: within this loop
7 | for (unsigned x = 0; x < level; x++) {
| ^~~
../gcc_bug.c:9:26: warning: '__builtin_memset' writing 17179869176 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:9:26: warning: '__builtin_memset' writing 17179869172 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:9:26: warning: '__builtin_memset' writing 17179869168 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:9:26: warning: '__builtin_memset' writing 17179869168 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
In function 'encode_block',
inlined from 'encode_block.constprop' at ../gcc_bug.c:17:18:
../gcc_bug.c:9:26: warning: '__builtin_memset' writing 17179869172 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:9:26: warning: '__builtin_memset' writing 17179869168 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
../gcc_bug.c:9:26: warning: '__builtin_memset' writing 17179869168 bytes into a
region of size 0 overflows the destination [-Wstringop-overflow=]
9 | block2[level][x] = 0;
| ~~~~~~~~~~~~~~~~~^~~
If one adds -Wall, one gets -Warray-bounds warnings instead of
-Wstringop-overflow= warnings.
This happens in latest git master; I bisected it to
9b14fc3326e087975653b1af8ac54114041cde51. None of the other open
-Warray-bounds/-Wstringop-overflow= warnings have been traced back to this
commit, so I believe this bug report not to be a duplicate of one of the other
open bugs.
PS: The above is based upon
https://github.com/FFmpeg/FFmpeg/blob/56e9e0273a79fb4ff4276503e69981f8e383f22b/libavcodec/svq1enc.c#L91
This code is covered by our regression tests and none of them fail, so GCC does
not seem to miscompile it (despite the warnings indicating GCC's internal state
to be garbage).
(Somehow the warning is not triggered by
9b14fc3326e087975653b1af8ac54114041cde51 for this file: The warnings only
appeared with GCC 11, GCC 10 is fine. I did not bisect this further. For
another one of our files
(https://github.com/FFmpeg/FFmpeg/blob/8be701d9f7f77ff2282cc7fe6e0791ca5419de70/libavfilter/vf_find_rect.c#L157)
the warnings appeared with 9b14fc3326e087975653b1af8ac54114041cde51 and are
also in GCC 10, yet somehow not in GCC 11 and also not in GCC master. I also
did not bisect this further, as the underlying bug is probably the same for
all, so fixing the testcase should fix all of it.)
More information about the Gcc-bugs
mailing list