https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80776

            Bug ID: 80776
           Summary: -Wformat-overflow false positive for %d on integer
                    bounded by __builtin_unreachable
           Product: gcc
           Version: 7.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eggert at gnu dot org
  Target Milestone: ---

I found this problem when compiling Emacs with GCC 7.1.0 on x86-64. Emacs uses
__builtin_unreachable to let the compiler know about ranges and thereby
suppress false alarms. Here is a stripped-down example of the bug:

  extern int sprintf (char *restrict, const char *restrict, ...)
    __attribute__ ((__nothrow__));
  extern int foo (void);

  int
  Fgenerate_new_buffer_name (void)
  {
    char number[2];
    int i = foo ();
    if (i < 0)
      __builtin_unreachable ();
    if (i >= 2)
      __builtin_unreachable ();
    return sprintf (number, "%d", i);
  }

Compile this with:

  gcc -c -Wformat-overflow -O2  t.i

The output is:

t.i: In function 'Fgenerate_new_buffer_name':
t.i:14:28: warning: '%d' directive writing between 1 and 10 bytes into a
region\
 of size 2 [-Wformat-overflow=]
   return sprintf (number, "%d", i);
                            ^~
t.i:14:27: note: directive argument in the range [0, 2147483647]
   return sprintf (number, "%d", i);
                           ^~~~

The diagnostic is incorrect, as the directive argument I is in the range [0,
1]. Changing the two ifs to read just "if (i < 0 || i >= 2)
__builtin_unreachable ();" works around this particular bug, but other variants
show similar problems.

Reply via email to