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 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~