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.

Reply via email to