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

            Bug ID: 79376
           Summary: wrong lower bound with %s and non-constant strings in
                    -Wformat-overflow
           Product: gcc
           Version: 7.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: ---

The -Wformat-overflow warning prints the wrong lower bound for %s directives
with arguments involving both strings and character arrays of known bound (but
unknown length).  In the test case below the length of either a->a5 or a->a7
may be zero and so while the warning itself is justified (because "12" doesn't
fit and the length of either of the arrays may also be greater than 1) the
lower bound should be zero.

Since the lower bound is also used in the sprintf return value optimization the
problem can cause the wrong code to be generated.

$ cat t.c && gcc -O2 -S -Wall t.c
char d[1];

struct A { char a5[5]; char a7[7]; int i; };

int f (struct A *a)
{
  char *s = a->i < 0 ? a->a5 : 0 < a->i ? a->a7 : "12";

  return __builtin_sprintf (d, "%-s", s);
}
t.c: In function ‘f’:
t.c:9:33: warning: ‘%-s’ directive writing between 2 and 6 bytes into a region
of size 1 [-Wformat-overflow=]
   return __builtin_sprintf (d, "%-s", s);
                                 ^~~
t.c:9:10: note: ‘__builtin_sprintf’ output between 3 and 7 bytes into a
destination of size 1
   return __builtin_sprintf (d, "%-s", s);
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to