[Bug middle-end/78154] New: memcpy et al can be assumed to return non-null

msebor at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat Oct 29 02:50:00 GMT 2016


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

            Bug ID: 78154
           Summary: memcpy et al can be assumed to return non-null
           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: ---

memcpy and other string manipulation functions declkared in <string.h> (e.g.,
memset, strcpy, etc.) that return their first argument are required to be
called with a non-null pointer as that argument.  Therefore, the functions'
return value can be assumed to be non-null (certainly when it is known that
they must rely on that precondition, such as when the number of bytes they copy
is known to be non-zero).  This postcondition could be exploited in further
optimizations downstream.  The test case below shows that GCC does not
currently take advantage of this postcondition, likely because the intrinsic
functions are not decorated with attribute returns_nonnull.

$ cat b.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout b.c
extern char* memcpy (void*, const void*, __SIZE_TYPE__);

void f (void *d, const void *s, __SIZE_TYPE__ n)
{
  if (n && memcpy (d, s, n) == 0)
    __builtin_abort ();
}


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

Removing basic block 6
Removing basic block 7
f (void * d, const void * s, long unsigned int n)
{
  char * _1;

  <bb 2>:
  if (n_3(D) != 0)
    goto <bb 3>;
  else
    goto <bb 5>;

  <bb 3>:
  _1 = memcpy (d_5(D), s_6(D), n_3(D));
  if (_1 == 0B)
    goto <bb 4>;
  else
    goto <bb 5>;

  <bb 4>:
  __builtin_abort ();

  <bb 5>:
  return;

}


More information about the Gcc-bugs mailing list