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; }