https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90662
--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The inequality in g() should be != 3, not != 5:
void g (int n)
{
char a[n];
__builtin_strcpy (a, "12345");
if (__builtin_strlen (&a[2]) != 3) // not folded
__builtin_abort ();
}
The expression '&*a.1_9[2]' in the GIMPLE can be traced to the original IL
(below). I wonder how many other transformations make the same assumption as
strlen that such ADDR_EXPRs are simplified into POINTER_PLUS_EXPRs.
;; Function g (null)
;; enabled by -tree-original
{
char a[0:(sizetype) ((long int) SAVE_EXPR <n> + -1)];
(void) SAVE_EXPR <n>;
char a[0:(sizetype) ((long int) SAVE_EXPR <n> + -1)];
__builtin_strcpy ((char *) &a, (const char *) "12345");
if (__builtin_strlen ((const char *) &a[2]) != 3)
{
__builtin_abort ();
}
}
;; Function h (null)
;; enabled by -tree-original
{
char * a = (char *) __builtin_malloc (6);
char * a = (char *) __builtin_malloc (6);
__builtin_strcpy (a, (const char *) "12345");
if (__builtin_strlen ((const char *) (a + 2)) != 3)
{
__builtin_abort ();
}
}