https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120929
--- Comment #7 from Sergei Trofimovich <slyfox at gcc dot gnu.org> --- (In reply to qinzhao from comment #6) > (In reply to Sergei Trofimovich from comment #3) > > (In reply to qinzhao from comment #2) > > > could you please reduce the testing case to help me debug? > > > > Will do. Might take some time as I'm not very familiar with `file` code > > base. > > Thanks a lot. will you use C-reduce to reduce the testing case? > I tried your instructions in the Description part to > git clone, autoreconf -ivf, these have no issues, but when make I'm afraid I reduce wrong-code manually to make sure transformations are not too bad. > [opc@qinzhao-ol8u3-x86 file]$ make > make: *** No targets specified and no makefile found. Stop. > > did I do anything wrong? I missed a few crucial steps like default CFLAGS. My apologies. Here is more isolated example instead. I'm a bit more confident it's gcc's problem of inferring wrong target object size after some optimization. It still needs glibc, but if you would not be able to reproduce I'll preprocess it as well (I suspect memcpy() macro is crucial there). The example: // $ cat apprentice.c // $ /nix/store/925dmxv72ap648ipwnswz5lx4j8xp11d-gcc-wrapper-16.0.0.99999999/bin/gcc -D_FORTIFY_SOURCE=3 apprentice.c -O1 -o bug && ./bug #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> struct magic_ { char unused[9]; // at least 9 }; struct magic_map { struct magic_ *magic[1]; }; static int coalesce_entries(struct magic_ **ma) { uint32_t i, mentrycount = 0; size_t slen; for (i = 0; i < 1; i++) { mentrycount += 1; } slen = sizeof(**ma) * mentrycount; *ma = malloc(slen); mentrycount = 0; for (i = 0; i < 1; i++) { char b[1024] = {}; (void)memcpy(*ma + mentrycount, b, 1 * sizeof(**ma)); mentrycount += 1; } return 0; } __attribute__((noipa)) static void pin_pointer(void *){} __attribute__((noipa)) static int some_value(void){ return 1; } __attribute__((optimize(1))) // (2) makes it disappear __attribute__((noipa)) static struct magic_map * apprentice_load(void) { char buf[128]; // did not shrink, but needs to be more than 100 struct magic_map *map2; map2 = calloc(1, sizeof(*map2)); pin_pointer(&buf); if (some_value() == 42) { // does not really execute, but needed for complex control flow goto out; } coalesce_entries(&map2->magic[0]); pin_pointer(map2); out: return map2; } int main() { apprentice_load(); } Crashing: $ gcc/xgcc -Bgcc -D_FORTIFY_SOURCE=3 -O1 apprentice.c -o bug && ./bug In file included from /usr/include/string.h:548, from apprentice.c:4: In function 'memcpy', inlined from 'coalesce_entries' at apprentice.c:30:9, inlined from 'apprentice_load' at apprentice.c:59:3: /usr/include/bits/string_fortified.h:29:10: warning: '__builtin___memcpy_chk' writing 9 bytes into a region of size 8 overflows the destination [-Wstringop-overflow=] 29 | return __builtin___memcpy_chk (__dest, __src, __len, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 30 | __glibc_objsize0 (__dest)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ *** buffer overflow detected ***: terminated Aborted (core dumped) Compiler details: $ gcc/xgcc -Bgcc -v Reading specs from gcc/specs COLLECT_GCC=gcc/xgcc COLLECT_LTO_WRAPPER=gcc/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /home/slyfox/dev/git/gcc/configure --disable-multilib --disable-bootstrap --disable-lto --disable-libsanitizer --enable-languages=c CFLAGS='-O1 -g0' CXXFLAGS='-O1 -g0' LDFLAGS='-O1 -g0' Thread model: posix Supported LTO compression algorithms: zlib gcc version 16.0.0 20250702 (experimental) (GCC)