https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119320
Bug ID: 119320
Summary: unexpected -Wstringop-overflow= when using memcpy
Product: gcc
Version: 14.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: b07902028 at csie dot ntu.edu.tw
Target Milestone: ---
Hi,
On Arch-linux with gcc 14.2.1, we found that a Wstringop-overflow warning
popped out when the following codes are compiled with
g++ -Wall -Wconversion -O3 -fPIC -g -DNDEBUG -Wextra -fno-exceptions -std=c++11
-c test.cpp
============================
#include <string.h>
static inline void clone_double(double*& dst, const double* src, int n)
{
dst = new double[n];
size_t len = sizeof(double)*n;
memcpy(dst, src, len);
}
int *ptr;
double *p;
void solve(int l, const double *p_)
{
clone_double(p, p_,l);
ptr = new int[l]; // the warning disappears when I comment this line
}
===========================
warning messages:
In function ‘void clone_double(double*&, const double*, int)’,
inlined from ‘void solve(int, const double*)’ at test.cpp:31:17:
test.cpp:22:15: warning: ‘void* memcpy(void*, const void*, size_t)’ writing
between 18446744056529682432 and 18446744073709551608 bytes into a region of
size 9223372036854775807 [-Wstringop-overflow=]
22 | memcpy(dst, src, len);
| ~~~~~~^~~~~~~~~~~~~~~
test.cpp:20:23: note: destination object of size 9223372036854775807 allocated
by ‘operator new []’
20 | dst = new double[n];
| ^
============================
I don't know how the compiler estimates the size we're going to write.
Besides, by commenting the "ptr = new int[l];" line, the warning disappears.
Thus, we regard this as a bug from the glibc_obj0(..)
On the other hand, on another machine with ubuntu 22.04 / gcc 11.4.0,
running the following codes lead to similar warning message.
Also, commenting the "ptr = new int[l];" line also make the warning disappears.
g++ -Wall -Wconversion -O3 -fPIC -g -DNDEBUG -Wextra -fno-exceptions
-Wno-unused-parameter -std=c++11 -c overflow_codes.cpp
overflow_codes.cpp
=============================
#include <string.h>
typedef signed char schar;
static inline void clone_schar(schar*& dst, const schar* src, int n)
{
dst = new schar[n];
memcpy(dst, src, sizeof(schar)*n);
}
static inline void clone_double(double*& dst, const double* src, int n)
{
dst = new double[n];
memcpy(dst, src, sizeof(double)*n);
}
int *ptr;
double *p;
schar *y;
void solve(int l, const double *p_, const schar *y_)
{
clone_double(p, p_,l);
clone_schar(y, y_,l);
ptr = new int[l];
}
===================================
In file included from /usr/include/string.h:535,
from overflow_codes.cpp:23:
In function ‘void* memcpy(void*, const void*, size_t)’,
inlined from ‘void clone_schar(schar*&, const schar*, int)’ at
overflow_codes.cpp:29:8,
inlined from ‘void solve(int, const double*, const schar*)’ at
overflow_codes.cpp:45:16:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:33: warning: ‘void*
__builtin_memcpy(void*, const void*, long unsigned int)’ writing between
18446744071562067968 and 18446744073709551615 bytes into a region of size
between 0 and 2147483647 [-Wstringop-overflow=]
29 | return __builtin___memcpy_chk (__dest, __src, __len,
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
30 | __glibc_objsize0 (__dest));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
overflow_codes.cpp: In function ‘void solve(int, const double*, const schar*)’:
overflow_codes.cpp:28:22: note: destination object of size [0, 2147483647]
allocated by ‘operator new []’
28 | dst = new schar[n];
| ^
Thanks for your kind helping in advance.
Feel free to ask me for more information.