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

            Bug ID: 84771
           Summary: missing -Wrestrict passing the same address to
                    restrict-qualified arguments of a user-defined
                    function
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

In the test case below, -Wrestrict detects the first four instances of passing
the same address to restrict-qualified arguments but misses the last two in the
call to the user-defined function.

The reason for that is that the checker for user-defined functions is
implemented in the front-end and relies on operand_equal_p() to determine
whether the arguments are equal, which isn't equipped to do this kind of
analysis.  To do a better job this part of the checker (i.e., for user-defined
functions) should be moved to the gimple-ssa-warn-restrict pass.

$ cat x.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout x.c
struct S { char a[4]; };

void f (struct S *p)
{
  __builtin_strcpy ((char*)p, (char*)p);   // -Wrestrict (good)
  __builtin_strcpy ((char*)p, p->a);       // -Wrestrict (good)
  __builtin_strcpy ((char*)p, &p->a[0]);   // -Wrestrict (good)
}

void g (void* restrict, void* restrict);

void h (struct S *p)
{
  g (p, p);                                // -Wrestrict (good)
  g (p, p->a);                             // missing -Wrestrict
  g (p->a, &p->a[0]);                      // missing -Wrestrict
}
x.c: In function ‘h’:
x.c:14:3: warning: passing argument 1 to restrict-qualified parameter aliases
with argument 2 [-Wrestrict]
   g (p, p);                                // -Wrestrict (good)
   ^
x.c: In function ‘f’:
x.c:5:3: warning: ‘__builtin_strcpy’ source argument is the same as destination
[-Wrestrict]
   __builtin_strcpy ((char*)p, (char*)p);   // -Wrestrict (good)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x.c:6:3: warning: ‘__builtin_strcpy’ accessing 1 byte at offsets 0 and 0
overlaps 1 byte at offset 0 [-Wrestrict]
   __builtin_strcpy ((char*)p, p->a);       // -Wrestrict (good)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
x.c:7:3: warning: ‘__builtin_strcpy’ accessing 1 byte at offsets 0 and 0
overlaps 1 byte at offset 0 [-Wrestrict]
   __builtin_strcpy ((char*)p, &p->a[0]);   // -Wrestrict (good)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

f (struct S * p)
{
  char[4] * _1;

  <bb 2> [local count: 1073741825]:
  _1 = &p_2(D)->a;
  __builtin_strcpy (p_2(D), _1);
  __builtin_strcpy (p_2(D), _1); [tail call]
  return;

}



;; Function h (h, funcdef_no=1, decl_uid=1966, cgraph_uid=1, symbol_order=1)

h (struct S * p)
{
  char[4] * _1;

  <bb 2> [local count: 1073741825]:
  g (p_3(D), p_3(D));
  _1 = &p_3(D)->a;
  g (p_3(D), _1);
  g (_1, _1); [tail call]
  return;

}

Reply via email to