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

            Bug ID: 77357
           Summary: strlen of constant strings not folded
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

GCC successfully folds some simple calls to strlen with constant arguments but
not others, both with and without optimization.  The results with optimization
are somewhat better but still not as good as they could be.  Besides opening up
other optimization opportunities, improving folding (even without optimization)
will help detect more coding bugs (such as buffer overflows).

The following test case shows that GCC folds global constant character arrays
and constant pointers to string literals but it fails to do the same for static
local const arrays or pointers or global aggregates.

With optimization, it still fails to fold const aggregates and ends up calling
strlen.

$ cat xyz.c && /build/gcc-trunk-svn/gcc/xgcc -B /build/gcc-trunk-svn/gcc -O0 -S
-Wall -Wextra -Wpedantic -fdump-tree-optimized=/dev/stdout strlen.c
extern int vsprintf (char*, const char*, __builtin_va_list);

void g (char *d, __builtin_va_list va)
{
  const char f[] = "%i";
  vsprintf (d, f, va);
}

void h (char *d, const char *f, __builtin_va_list va)
{
  vsprintf (d, f, va);
}


;; Function global_array (global_array, funcdef_no=0, decl_uid=1756,
cgraph_uid=0, symbol_order=3)

global_array ()
{
  <bb 2>:

  <bb 3>:
  return;

}



;; Function global_pointer (global_pointer, funcdef_no=1, decl_uid=1759,
cgraph_uid=1, symbol_order=4)

global_pointer ()
{
  const char * s.0_1;
  long unsigned int _2;

  <bb 2>:
  s.0_1 = "abc";
  _2 = 3;
  if (_2 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  return;

}



;; Function local_array (local_array, funcdef_no=2, decl_uid=1762,
cgraph_uid=2, symbol_order=5)

local_array ()
{
  static const char a[4] = "abc";
  long unsigned int _1;

  <bb 2>:
  _1 = __builtin_strlen (&a);
  if (_1 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  return;

}



;; Function local_pointer (local_pointer, funcdef_no=3, decl_uid=1766,
cgraph_uid=3, symbol_order=6)

local_pointer ()
{
  const char * const s;
  long unsigned int _1;

  <bb 2>:
  s_2 = "abc";
  _1 = __builtin_strlen (s_2);
  if (_1 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  return;

}



;; Function global_struct (global_struct, funcdef_no=4, decl_uid=1770,
cgraph_uid=4, symbol_order=7)

global_struct ()
{
  long unsigned int _1;

  <bb 2>:
  _1 = __builtin_strlen (&x.a);
  if (_1 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  return;

}



;; Function local_struct (local_struct, funcdef_no=5, decl_uid=1773,
cgraph_uid=5, symbol_order=8)

local_struct ()
{
  static const struct X x = {.a="abc"};
  long unsigned int _1;

  <bb 2>:
  _1 = __builtin_strlen (&x.a);
  if (_1 != 3)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  __builtin_abort ();

  <bb 4>:
  return;

}

Reply via email to