https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86955
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2019-06-07 Ever confirmed|0 |1 Known to fail| |10.0, 5.1.0, 6.4.0, 7.3.0, | |8.2.0, 9.1.0 --- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> --- Confirming. The following is also not folded. struct S { char n, a[8]; }; void f4 (struct S *s) { __builtin_strcpy (s->a, "123"); if (__builtin_strlen (&s->a[1]) != 2) __builtin_abort (); } The pass sees that the strlen argument _2 is defined to &s_4(D)->a[1], and it has a record of of the length of &s_4(D)->a, so it should be able to compute the length. It doesn't because the get_stridx() only handles POINTER_PLUS_EXPR and not ARRAY_REF or COMPONENT_REF. Handling that shouldn't be difficult. ;; Function f4 (f4, funcdef_no=0, decl_uid=1909, cgraph_uid=1, symbol_order=0) f4 (struct S * s) { char[8] * _1; char * _2; long unsigned int _3; <bb 2> [local count: 1073741824]: _1 = &s_4(D)->a; __builtin_memcpy (_1, "123", 4); _2 = &s_4(D)->a[1]; _3 = __builtin_strlen (_2); if (_3 != 2) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return; }