This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/71319] New: unnecessary call to __strcat_chk emitted after buffer reset


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

            Bug ID: 71319
           Summary: unnecessary call to __strcat_chk emitted after buffer
                    reset
           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: ---

Similar to bug 71304, in the following test case, since the string in the
destination buffer is truncated at a known offset after it has been copied
there by the checked call, the subsequent strcat call doesn't need to expand to
a checked call because there is enough space in the buffer to append the source
string to its contents.  GCC performs this optimization in the first test case
(function f) when the string a truncated by calling strcpy, but it doesn't do
the same thing when the string is truncated by inserting a NUL into the same
position.

$ cat strcat.c && /home/msebor/build/gcc-6-branch/gcc/xgcc
-B/home/msebor/build/gcc-6-branch/gcc -O2 -S -fdump-tree-optimized=/dev/stdout
strcat.c
#define strcat(d, s)\
  __builtin___strcat_chk (d, s, __builtin_object_size (d, 0))

#define strcpy(d, s) \
  __builtin___strcpy_chk (d, s, __builtin_object_size (d, 0))

void sink (const char*);

int f (const char *s)
{
  char a [4] = "1";
  strcat (a, "2");   // safe
  strcat (a, s);     // must be checked

  strcpy (a, "1");
  strcat (a, "3");   // safe

  sink (a);
}

int g (const char *s)
{
  char a [4] = "1";
  strcat (a, "2");   // safe
  strcat (a, s);     // must be checked

  a [1] = '\0';
  strcat (a, "3");   // safe but checked (missing optimization)

  sink (a);
}


;; Function f (f, funcdef_no=0, decl_uid=1758, cgraph_uid=0, symbol_order=0)

f (const char * s)
{
  char a[4];

  <bb 2>:
  a = "1";
  __builtin___strcpy_chk (&MEM[(void *)&a + 2B], s_4(D), 4);
  MEM[(char * {ref-all})&a] = 49;
  __builtin_memcpy (&MEM[(void *)&a + 1B], "3", 2);
  sink (&a);
  a ={v} {CLOBBER};
  return;

}



;; Function g (g, funcdef_no=1, decl_uid=1762, cgraph_uid=1, symbol_order=1)

g (const char * s)
{
  char a[4];

  <bb 2>:
  a = "1";
  __builtin___strcpy_chk (&MEM[(void *)&a + 2B], s_4(D), 4);
  a[1] = 0;
  __builtin___strcat_chk (&a, "3", 4);
  sink (&a);
  a ={v} {CLOBBER};
  return;

}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]