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;

}

Reply via email to