https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128170
Bug ID: 128170
Summary: [14/15/16/17 Regression] strlen pass keeps a string
length across an aliasing store after strlen of a
suffix
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: lzy20000419 at outlook dot com
Target Milestone: ---
__attribute__((noipa)) unsigned long
f (char *b, char *q)
{
b[0] = 'x'; b[1] = 'y';
unsigned long n = __builtin_strlen (b + 2);
*q = 0;
return n * 1000 + __builtin_strlen (b);
}
int
main (void)
{
char buf[16] = "0123456789";
if (f (buf, buf + 2) != 8 * 1000 + 2)
__builtin_abort ();
return 0;
}
$ gcc -O2 t.c && ./a.out Aborted
Expected: no abort. q points to b + 2, so after *q = 0 strlen (b) is 2. At
-O2/-O3 f returns 8010: the second strlen is replaced by n + 2. -O1, -O2
-fno-optimize-strlen and clang are fine; -fsanitize=address,undefined is clean.
It fails with 8.1 through 16.2 and trunk; 7.5 is fine (also with
noinline,noclone instead of noipa, which 7.5 does not know).
https://godbolt.org/z/dG44M1rcE (left gcc 7.5, right trunk)
Disclaimer: This test case was generated by a fuzzer, and the report was
written with LLM assistance.