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

            Bug ID: 93517
           Summary: bogus -Wrestrict on sprintf with unknown strings
                    bounded by array size
           Product: gcc
           Version: 10.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: ---

The warning below is incorrect because (assuming a is a nul-terminated string)
the length of s1 must be at most 1 and the length of s2 is necessarily zero. 
As a result, the sprintf call writes at most two bytes into the array while
reading from it beginning at offset 2.

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

void f (void)
{
  char *d = a;
  char *s1 = a + 2;
  char *s2 = a + 3;

  __builtin_sprintf (d, "%s%s", s1, s2);
}
a.c: In function ‘f’:
a.c:9:3: warning: ‘__builtin_sprintf’ arguments 3, 4 may overlap destination
object ‘a’ [-Wrestrict]
    9 |   __builtin_sprintf (d, "%s%s", s1, s2);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a.c:1:6: note: destination object referenced by ‘restrict’-qualified argument 1
was declared here
    1 | char a[4];
      |      ^

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

f ()
{
  <bb 2> [local count: 1073741824]:
  __builtin_sprintf (&a, "%s%s", &MEM <char[4]> [(void *)&a + 2B], &MEM
<char[4]> [(void *)&a + 3B]); [tail call]
  return;

}

Reply via email to