https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123219
Bug ID: 123219
Summary: False positive stringop-overflow if optimization is
active
Product: gcc
Version: 15.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: tobias.trauth at x2e dot de
Target Milestone: ---
Hello all,
I think I found a false positive warning (stringop-overflow).
I just wrote a memcpy like function. First it seems all to work:
#include <cstdio>
#include <string>
#include <cstdint>
static void copy(char* dst, const char* src_start, const char* src_end)
{
while(src_start != src_end)
{
*dst = *src_start;
++src_start;
++dst;
}
}
static void print(const char* buffer, size_t size)
{
for(size_t i = 0; i < size; ++i)
printf("%x ", static_cast<uint8_t>(buffer[i]));
printf("\n");
}
int main()
{
std::string s = "123";
char buffer[10]{0};
printf(buffer, sizeof(buffer));
copy(buffer, &s[0], &s[s.size()]);
print(buffer, sizeof(buffer));
}
However, calling the print function before the copy function triggers many
warnings.
As soon I compile with -O0 the warnings disappear.
As far as I can tell, this has been happening since gcc 11
You can find the example at compilerexplorer.org as well:
https://godbolt.org/z/Y8jsx3TWf
Compiler arguments: --std=c++17 -O3 -Wall -Werror -Wextra -Wshadow
Warnings:
In function 'void copy(char*, const char*, const char*)',
inlined from 'int main()' at <source>:29:9:
<source>:9:14: error: writing 1 byte into a region of size 0
[-Werror=stringop-overflow=]
9 | *dst = *src_start;
| ~~~~~^~~~~~~~~~~~
<source>: In function 'int main()':
<source>:26:10: note: at offset [18, 9223372036854775802] into destination
object 'buffer' of size 10
26 | char buffer[10]{0};
| ^~~~~~
<source>:26:10: note: at offset [2, 10] into destination object 'buffer' of
size 10
<source>:26:10: note: at offset [18, 9223372036854775802] into destination
object 'buffer' of size 10
In function 'void copy(char*, const char*, const char*)',
inlined from 'int main()' at <source>:29:9:
<source>:9:14: error: writing 1 byte into a region of size 0
[-Werror=stringop-overflow=]
9 | *dst = *src_start;
| ~~~~~^~~~~~~~~~~~
<source>: In function 'int main()':
<source>:26:10: note: at offset [19, 9223372036854775803] into destination
object 'buffer' of size 10
26 | char buffer[10]{0};
| ^~~~~~
<source>:26:10: note: at offset [3, 10] into destination object 'buffer' of
size 10
<source>:26:10: note: at offset [19, 9223372036854775803] into destination
object 'buffer' of size 10
In function 'void copy(char*, const char*, const char*)',
inlined from 'int main()' at <source>:29:9:
<source>:9:14: error: writing 1 byte into a region of size 0
[-Werror=stringop-overflow=]
9 | *dst = *src_start;
| ~~~~~^~~~~~~~~~~~
<source>: In function 'int main()':
<source>:26:10: note: at offset [20, 9223372036854775804] into destination
object 'buffer' of size 10
26 | char buffer[10]{0};
| ^~~~~~
<source>:26:10: note: at offset [4, 10] into destination object 'buffer' of
size 10
<source>:26:10: note: at offset [20, 9223372036854775804] into destination
object 'buffer' of size 10
In function 'void copy(char*, const char*, const char*)',
inlined from 'int main()' at <source>:29:9:
<source>:9:14: error: writing 1 byte into a region of size 0
[-Werror=stringop-overflow=]
9 | *dst = *src_start;
| ~~~~~^~~~~~~~~~~~
<source>: In function 'int main()':
<source>:26:10: note: at offset [21, 9223372036854775805] into destination
object 'buffer' of size 10
26 | char buffer[10]{0};
| ^~~~~~
<source>:26:10: note: at offset [5, 10] into destination object 'buffer' of
size 10
<source>:26:10: note: at offset [21, 9223372036854775805] into destination
object 'buffer' of size 10
In function 'void copy(char*, const char*, const char*)',
inlined from 'int main()' at <source>:29:9:
<source>:9:14: error: writing 1 byte into a region of size 0
[-Werror=stringop-overflow=]
9 | *dst = *src_start;
| ~~~~~^~~~~~~~~~~~
<source>: In function 'int main()':
<source>:26:10: note: at offset [22, 9223372036854775806] into destination
object 'buffer' of size 10
26 | char buffer[10]{0};
| ^~~~~~
<source>:26:10: note: at offset [6, 10] into destination object 'buffer' of
size 10
<source>:26:10: note: at offset [22, 9223372036854775806] into destination
object 'buffer' of size 10