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;

}

Reply via email to