https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86851
Bug ID: 86851
Summary: missing -Wformat-overflow on %s with a constant string
plus variable offset
Product: gcc
Version: 9.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: ---
Even though it's possible to determine the range of lengths of the constant
string in the sprintf call below the sprintf pass fails to do so and so misses
the buffer overflow and also emits suboptimal code. The problem is in the
string_constant function failing to determine the string the &a[i] expression
refers to. The expression the function sees is SSA_NAME (L"123...") + offset
but it only handles ADDR_EXPR, PLUS_EXPR/POINTER_PLUS_EXPR, and DECL.
$ cat d.c && gcc -O2 -S -Wall -fdump-tree-printf-return-value=/dev/stdout d.c
static const char a[] = "123456789";
char d[4];
void f (int i)
{
if (i > 2)
i = 2;
__builtin_sprintf (d, "%s", &a[i]);
}
;; Function f (f, funcdef_no=0, decl_uid=1907, cgraph_uid=1, symbol_order=2)
d.c:10: __builtin_sprintf: objsize = 4, fmtstr = "%s"
Directive 1 at offset 0: "%s"
Result: 0, 0, -1, 9223372036854775807 (0, 0, -1, -1)
Directive 2 at offset 2: "", length = 1
f (int i)
{
const char * _1;
sizetype _2;
<bb 2> [local count: 1073741825]:
i_6 = MIN_EXPR <i_3(D), 2>;
_2 = (sizetype) i_6;
_1 = &a + _2;
__builtin_strcpy (&d, _1);
return;
}