https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86259
--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> --- Btw, GCC still claims to support C89, so please cite appropriate C89 wording. To GCC internals while a direct access like a.b.c[i].d has to remain inside bounds the variant via a pointer p = &a.b.c[i].d; ... = *p; does not have such restrictions. Thus once a function call is involved like strlen (&a.b.c[0].d), the actual access is via a pointer (in the strlen implementation) and thus GCC doesn't (and may not) assume the access stays inside bounds. This is the very reason that we avoid propagating the pointer example above to ... = *(&a.b.c[i].d) = a.b.c[i].d; because to GCC that is not an identity transform semantically.