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/78452] -Wformat-length=2 wrong length in %s directive with an array argument


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

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |FIXED
           Assignee|unassigned at gcc dot gnu.org      |msebor at gcc dot gnu.org
   Target Milestone|---                         |7.0

--- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> ---
The latest trunk (GCC 7.0) doesn't issue the second warning due to bug 79538. 
Changing the test case to get around that limitation and trigger the warning
shows that the warning and the subsequent note are now correct.  The warning
says "may write a terminating nul past the end of the destination" is correct
because when the longer of the two arrays holds the longest string that can fit
(one whose length is 3 bytes) the function will write the terminating nul just
past the end.  Because the string could be shorter than that, the warning
correctly says "may write."  The note then explains that the total number of
bytes written by the function is between 1 byte (for the nul alone when the
string is empty) and 4 bytes (when the string length is 3, plus the terminating
nul).


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

const char s3[] = "123";
const char s4[] = "1234";

void f (int i)
{
  const char *s = i < 0 ? s3 : s4;
  __builtin_sprintf (d, "%-s", s);   // warning (expected), bytes correct
}

struct S
{
  char a3[3];
  char a4[4];
  int i;
};

void g (int i, struct S *p)
{
  const char *s = i < 0 ? p->a3 : p->a4;
  __builtin_sprintf (d, "%-s", s);   // warning (expected), bytes wrong
}
t.c: In function ‘f’:
t.c:9:26: warning: ‘%-s’ directive writing between 3 and 4 bytes into a region
of size 3 [-Wformat-overflow=]
   __builtin_sprintf (d, "%-s", s);   // warning (expected), bytes correct
                          ^~~
t.c:9:3: note: ‘__builtin_sprintf’ output between 4 and 5 bytes into a
destination of size 3
   __builtin_sprintf (d, "%-s", s);   // warning (expected), bytes correct
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.c: In function ‘g’:
t.c:22:25: warning: ‘__builtin_sprintf’ may write a terminating nul past the
end of the destination [-Wformat-overflow=]
   __builtin_sprintf (d, "%-s", s);   // warning (expected), bytes wrong
                         ^~~~~
t.c:22:3: note: ‘__builtin_sprintf’ output between 1 and 4 bytes into a
destination of size 3
   __builtin_sprintf (d, "%-s", s);   // warning (expected), bytes wrong
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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