https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117355
Siddhesh Poyarekar <siddhesh at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|unassigned at gcc dot gnu.org |siddhesh at gcc dot gnu.org Status|NEW |ASSIGNED --- Comment #11 from Siddhesh Poyarekar <siddhesh at gcc dot gnu.org> --- Even smaller reproducer: typedef unsigned long size_t; #define STR "string gds__)" void gen_blr (void) { char line[256]; const char *p = STR; const char *q = p + sizeof (STR) - 1; char *q1 = line; for (const char *p1 = p; p1 < q;) if ((*q1++ = *p1++) == 'g') if (p1 < q && (*q1++ = *p1++) == 'd') if (p1 < q && (*q1++ = *p1++) == 's') if (p1 < q && (*q1++ = *p1++) == '_') if (p1 < q && *p1++ == '_') __builtin___strncpy_chk (q1 - 4, "isc", 3, __builtin_dynamic_object_size (q1 - 4, 1)); } cc1plus ends up with a zero size while cc1 gets the conservative whole size, like Sam observed: $ gcc/cc1plus -quiet -O -o /dev/null ../firebird.ii ../firebird.ii: In function ‘void gen_blr()’: ../firebird.ii:19:39: warning: ‘char* __builtin___strncpy_chk(char*, const char*, long unsigned int, long unsigned int)’ writing 3 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=] 19 | __builtin___strncpy_chk (q1 - 4, "isc", 3, | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~ 20 | __builtin_dynamic_object_size | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 21 | (q1 - 4, 1)); | ~~~~~~~~~~~~ $ gcc/cc1 -quiet -O -o /dev/null ../firebird.ii $