https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126344
Bug ID: 126344
Summary: Spurious -Wformat-truncation= warning with
-Wno-stringop-overflow
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: aaron.puchert at sap dot com
Target Milestone: ---
Compile the following code with "g++ -c -O2 -D_FORTIFY_SOURCE=1 -Wall
-Wno-stringop-overflow":
#include <stdio.h>
static constexpr int bufsize = 256;
static char buf[bufsize];
void print(int *values, int count)
{
int pos = 0;
for (int i = 0; pos < bufsize && i < count; ++i) {
int result = snprintf(buf + pos, bufsize - pos, "%d\n", values[count]);
// if (result < 0) return;
pos += result;
}
if (pos >= bufsize)
printf("result too long");
}
This produces (with GCC 15 and later):
In file included from /usr/include/stdio.h:980,
from <source>:1:
In function 'int snprintf(char*, size_t, const char*, ...)',
inlined from 'void print(int*, int)' at <source>:10:30:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:54:35: warning: specified bound
2147483647 exceeds the size 256 of the destination object
[-Wformat-truncation=]
54 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 | __glibc_objsize (__s), __fmt,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56 | __va_arg_pack ());
| ~~~~~~~~~~~~~~~~~
There is no warning with GCC 14 and earlier. Several things are strange here:
* Removing -Wno-stringop-overflow makes the warning disappear, so this only
comes up when we disable -Wstringop-overflow.
* We should only have -Wformat-truncation=1 in -Wall, which is documented to
warn "only about calls to bounded functions whose return value is unused", but
the return value is clearly used. However, I have no indication that
-Wformat-truncation=2 is active: adding it explicitly produces a different
warning, and adding -Wformat-truncation=1 produces the same warning.
* The bound 2147483647 from the warning can only be reached with a large
negative pos (to be precise, 256 - 2147483647), which would require negative
return values from snprintf. My understanding is that the function returns
negative values only when being passed a null pointer. Just to be sure, I added
"if (result < 0) return;" (commented out above), but that doesn't change
anything.