Hi! For flexible array members we need to incrementally clear just from ptr + total_bytes up to new ptr + total_bytes, but memset has been called with the length from ptr, so was missing - total_bytes. Additionally, in this code off is guaranteed to be -1 and thus o 0, so don't bother pretending we could handle anything else, it would be more complicated than that.
Sorry for this brown paper bug, tested on x86_64-linux, committed to trunk as obvious. 2020-12-21 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/98407 * fold-const.c (native_encode_initializer): When handling flexible array members, fix up computation of length for memset. Also remove " - o" as o is always guaranteed to be 0 in this code path. * gcc.c-torture/compile/pr98407.c: New test. --- gcc/fold-const.c.jj 2020-12-19 22:24:03.945714395 +0100 +++ gcc/fold-const.c 2020-12-21 09:59:59.715313469 +0100 @@ -8280,9 +8280,9 @@ native_encode_initializer (tree init, un return 0; if (pos + fieldsize > total_bytes) { - if (ptr != NULL && total_bytes - o < len) - memset (ptr + (total_bytes - o), - '\0', MIN (pos + fieldsize - o, len)); + if (ptr != NULL && total_bytes < len) + memset (ptr + total_bytes, '\0', + MIN (pos + fieldsize, len) - total_bytes); total_bytes = pos + fieldsize; } } --- gcc/testsuite/gcc.c-torture/compile/pr98407.c.jj 2020-12-21 10:05:11.824717082 +0100 +++ gcc/testsuite/gcc.c-torture/compile/pr98407.c 2020-12-21 10:04:54.267919387 +0100 @@ -0,0 +1,10 @@ +/* PR tree-optimization/98407 */ + +struct S { int a; int b[]; }; +const struct S c = { 0, { 0 } }, d = { 0, { 0 } }; + +int +foo (void) +{ + return __builtin_memcmp (&c, &d, sizeof d); +} Jakub