https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121680
Bug ID: 121680 Summary: GCC 12/13/14 writing 8 bytes into a region of size 0 [-Wstringop-overflow=] with std::reverse on buffer Product: gcc Version: 14.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: szhong at perforce dot com Target Milestone: --- Created attachment 62205 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62205&action=edit testcase and preprocessed files It appears -fpeel-loops and -fvect-cost-model=dynamic from the -O3 flag is causing the -Wstringop-overflow warning. Can be reproduced with both GCC 12.2.1 and GCC 14.2.1 testcase: #include <string> #include <algorithm> template<typename T> size_t func(T val, char* s, size_t width) { size_t ret = 0; char* sbeg = s; char* send = s; do { *send++ = '0'; --width; } while ((val /= 10) && width > 0); ret += send - sbeg; std::reverse(sbeg, send); return ret; } struct Test { Test() : msec_(0) {} void test(); unsigned msec_; }; void Test::test() { char buf[256]; size_t i = 0; i += func(msec_, buf, 3); std::string(buf, i); } $ g++ -v -save-temps -m64 -O2 -fpeel-loops -fvect-cost-model=dynamic -c t.cpp Using built-in specs. COLLECT_GCC=g++ OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-redhat-linux Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --without-isl --enable-offload-targets=nvptx-none,amdgcn-amdhsa --enable-offload-defaulted --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_64=x86-64-v3 --with-arch_32=x86-64 --build=x86_64-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1 --enable-host-pie --enable-host-bind-now Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 14.2.1 20250110 (Red Hat 14.2.1-7) (GCC) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-m64' '-O2' '-fpeel-loops' '-fvect-cost-model=dynamic' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64-v3' /usr/libexec/gcc/x86_64-redhat-linux/14/cc1plus -E -quiet -v -D_GNU_SOURCE t.cpp -m64 -mtune=generic -march=x86-64-v3 -fpeel-loops -fvect-cost-model=dynamic -O2 -fpch-preprocess -o t.ii ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/14/include-fixed" ignoring nonexistent directory "/usr/lib/gcc/x86_64-redhat-linux/14/../../../../x86_64-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14 /usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/x86_64-redhat-linux /usr/lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/backward /usr/lib/gcc/x86_64-redhat-linux/14/include /usr/local/include /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-m64' '-O2' '-fpeel-loops' '-fvect-cost-model=dynamic' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64-v3' /usr/libexec/gcc/x86_64-redhat-linux/14/cc1plus -fpreprocessed t.ii -quiet -dumpbase t.cpp -dumpbase-ext .cpp -m64 -mtune=generic -march=x86-64-v3 -O2 -version -fpeel-loops -fvect-cost-model=dynamic -o t.s GNU C++17 (GCC) version 14.2.1 20250110 (Red Hat 14.2.1-7) (x86_64-redhat-linux) compiled by GNU C version 14.2.1 20250110 (Red Hat 14.2.1-7), GMP version 6.2.1, MPFR version 4.2.1, MPC version 1.3.1, isl version none GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: b89ee2dbc0f03a12df910586e15e87e1 In file included from /usr/include/c++/14/bits/new_allocator.h:36, from /usr/include/c++/14/x86_64-redhat-linux/bits/c++allocator.h:33, from /usr/include/c++/14/bits/allocator.h:46, from /usr/include/c++/14/string:43, from t.cpp:1: In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = char]’, inlined from ‘void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = char*; _ForwardIterator2 = char*]’ at /usr/include/c++/14/bits/stl_algobase.h:185:11, inlined from ‘void std::__reverse(_RandomAccessIterator, _RandomAccessIterator, random_access_iterator_tag) [with _RandomAccessIterator = char*]’ at /usr/include/c++/14/bits/stl_algo.h:1062:18, inlined from ‘void std::reverse(_BIter, _BIter) [with _BIter = char*]’ at /usr/include/c++/14/bits/stl_algo.h:1089:21, inlined from ‘size_t func(T, char*, size_t) [with T = unsigned int]’ at t.cpp:17:15, inlined from ‘void Test::test()’ at t.cpp:33:12: /usr/include/c++/14/bits/move.h:236:11: warning: writing 16 bytes into a region of size 0 [-Wstringop-overflow=] 236 | __b = _GLIBCXX_MOVE(__tmp); | ~~~~^~~~~~~~~~~~~~~~~~ t.cpp: In member function ‘void Test::test()’: t.cpp:31:8: note: at offset [9223372036854775794, 9223372036854775806] into destination object ‘buf’ of size 256 31 | char buf[256]; | ^~~ t.cpp:31:8: note: at offset 9223372036854775795 into destination object ‘buf’ of size 256 COLLECT_GCC_OPTIONS='-v' '-save-temps' '-m64' '-O2' '-fpeel-loops' '-fvect-cost-model=dynamic' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64-v3' as -v --64 -o t.o t.s GNU assembler version 2.41 (x86_64-redhat-linux) using BFD version version 2.41-53.el10 COMPILER_PATH=/usr/libexec/gcc/x86_64-redhat-linux/14/:/usr/libexec/gcc/x86_64-redhat-linux/14/:/usr/libexec/gcc/x86_64-redhat-linux/:/usr/lib/gcc/x86_64-redhat-linux/14/:/usr/lib/gcc/x86_64-redhat-linux/ LIBRARY_PATH=/usr/lib/gcc/x86_64-redhat-linux/14/:/usr/lib/gcc/x86_64-redhat-linux/14/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-redhat-linux/14/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-m64' '-O2' '-fpeel-loops' '-fvect-cost-model=dynamic' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64-v3' $ cat /etc/*release* NAME="Red Hat Enterprise Linux" VERSION="10.0 (Coughlan)" ID="rhel" ID_LIKE="centos fedora" VERSION_ID="10.0" PLATFORM_ID="platform:el10" PRETTY_NAME="Red Hat Enterprise Linux 10.0 (Coughlan)" ANSI_COLOR="0;31" LOGO="fedora-logo-icon" CPE_NAME="cpe:/o:redhat:enterprise_linux:10::baseos" HOME_URL="https://www.redhat.com/" VENDOR_NAME="Red Hat" VENDOR_URL="https://www.redhat.com/" DOCUMENTATION_URL="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/10" BUG_REPORT_URL="https://issues.redhat.com/" REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 10" REDHAT_BUGZILLA_PRODUCT_VERSION=10.0 REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" REDHAT_SUPPORT_PRODUCT_VERSION="10.0" Red Hat Enterprise Linux release 10.0 (Coughlan) Red Hat Enterprise Linux release 10.0 (Coughlan) cpe:/o:redhat:enterprise_linux:10::baseos Additional information: If I modify the testcase to pass the size of the buffer (256) into 'width' parameter, the warning goes away. Also if I add an additional parameter "buffer_size" and pass 3 into it, the warning also goes away. $ diff -u t.cpp t2.cpp --- t.cpp 2025-08-26 13:38:30.881143700 -0400 +++ t2.cpp 2025-08-26 13:38:10.365449874 -0400 @@ -2,7 +2,7 @@ #include <algorithm> template<typename T> -size_t func(T val, char* s, size_t width) { +size_t func(T val, char* s, size_t buffer_size, size_t width) { size_t ret = 0; char* sbeg = s; char* send = s; @@ -10,7 +10,7 @@ do { *send++ = '0'; --width; - } while ((val /= 10) && width > 0); + } while ((val /= 10) && buffer_size > 0 && width > 0); ret += send - sbeg; @@ -30,6 +30,6 @@ { char buf[256]; size_t i = 0; - i += func(msec_, buf, 3); + i += func(msec_, buf, 3, 3); std::string(buf, i); }