Created attachment 57493 [details] Preprocessed version of bug.c, in case it helps. When I compile the program below using: gcc -O3 bug.c -------------- extern int puts(const char *); #define CHAR_BIT 8 typedef unsigned long long ULongest; #define MPS_WORD_WIDTH (sizeof(void *) * CHAR_BIT) static void WriteULongest(ULongest w, unsigned base, unsigned width) { static const char digit[16 + 1] = "0123456789ABCDEF"; /* + 1 for terminator: unused, but prevents compiler warning */ static const char pad = '0'; /* padding character */ char buf[MPS_WORD_WIDTH + 1]; /* enough for binary, */ /* plus one for terminator */ unsigned i; /* Add digits to the buffer starting at the right-hand end, so that */ /* the buffer forms a string representing the number. A do...while */ /* loop is used to ensure that at least one digit (zero) is written */ /* when the number is zero. */ i = MPS_WORD_WIDTH; buf[i] = '\0'; do { --i; buf[i] = digit[w % base]; w /= base; } while(w > 0); /* If the number is not as wide as the requested field, pad out the */ /* buffer with zeros. */ while(i > MPS_WORD_WIDTH - width) { --i; buf[i] = pad; } puts(&buf[i]); } int main(int argc, const char *argv[]) { (void)argv; WriteULongest((ULongest)argc, 16, 1); // Note: Occurs for width = 0 and width = 1 return 0; } -------------- I get the following warning: ---------------- In function 'WriteULongest', inlined from 'main' at bug.c:44:2: bug.c:35:24: warning: '__builtin_memset' writing 4294967232 bytes into a region of size 2 overflows the destination [-Wstringop-overflow=] 35 | buf[i] = pad; | ~~~~~~~^~~~~ bug.c: In function 'main': bug.c:15:14: note: at offset 63 into destination object 'buf' of size 65 15 | char buf[MPS_WORD_WIDTH + 1]; /* enough for binary, */ | ^~~ ---------------- This happens when the last parameter (width) to the function WriteULongest is known to be either zero or one (see comment in the file). By inspecting the generated code (with -S), it seems like GCC transforms the second loop into a call to memset guarded by an if-statement similarly to below: if (i > 63) { memset(buf, '0', 4294967232); } The call to memset is indeed incorrect. However, GCC fails to consider that "i > 63" is never true, since "i" is initialized to 64 and then always decreased at least once in the previous loop. The call to memset could therefore be removed entirely. Output of gcc -v: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 13.2.0-13' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/reproducible-path/gcc-13-13.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/reproducible-path/gcc-13-13.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 13.2.0 (Debian 13.2.0-13)