https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83642

            Bug ID: 83642
           Summary: excessive strlen range after a strcat of non-empty
                    string
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The test case below (derived from bug 83640, comment #4) highlights a possible
optimization opportunity in the strlen pass.  So that the difference between
pointers to the first and just past the last byte of any array must be at most
PTRDIFF_MAX bytes the size of the largest array is PTRDIFF_MAX bytes.  Since
the length of the string literal appended to the DST array by the first strcat
call below is known to be 2, then length of the DST string must be less than
PTRDIFF_MAX - 2.  Therefore the test can be assumed to never evaluate to true
and the call to abort can be eliminated.

$ cat a.c && gcc -O2 -S -fdump-tree-vrp=/dev/stdout a.c
char *foo (void);

void
bar (char *dst, char *src)
{
  __SIZE_TYPE__ n = __builtin_strlen (dst);

  __builtin_strcat (dst, "*/");   // implies n < PTRDIFF_MAX - 3
  __builtin_strcat (dst, src);

  if (n >= __PTRDIFF_MAX__ - 2)   // must be false
    __builtin_abort ();           // can be eliminated
}

...
Value ranges after VRP:

dst_2(D): VARYING
n_3: [0, 9223372036854775806]
_4: VARYING
_9: [2, 9223372036854775808]
_10: VARYING
dst_11: ~[0B, 0B]  EQUIVALENCES: { dst_2(D) } (1 elements)


bar (char * dst, char * src)
{
  long unsigned int n;
  char * _4;
  long unsigned int _9;
  char * _10;

  <bb 2> [local count: 1073741825]:
  n_3 = __builtin_strlen (dst_2(D));
  _4 = dst_2(D) + n_3;
  __builtin_memcpy (_4, "*/", 2);
  _9 = n_3 + 2;
  _10 = dst_2(D) + _9;
  __builtin_strcpy (_10, src_6(D));
  if (n_3 > 9223372036854775804)
    goto <bb 3>; [0.00%]
  else
    goto <bb 4>; [99.96%]

  <bb 3> [count: 0]:
  __builtin_abort ();

  <bb 4> [local count: 1073312327]:
  return;

}

Reply via email to