https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80776
--- Comment #3 from Paul Eggert <eggert at gnu dot org> --- (In reply to Richard Biener from comment #1) > Possibly the walk in remove_range_assertions visits the latter before the > former block but in principle we do have code to handle this there. I just ran into the same problem again, with the following code derived from GNU Emacs, and it suggests that your diagnosis is correct. Perhaps this can be used in a test case once the bug is fixed. If I remove the "if (! (0 <= i)) __builtin_unreachable ();" the bogus warning goes away, which suggests that the earlier test is hiding the later one somehow. This is with GCC 7.2.1 20170915 (Red Hat 7.2.1-2) on x86-64. extern __inline __attribute__ ((__always_inline__)) __attribute__ ((__gnu_inline__)) __attribute__ ((__artificial__)) int __attribute__ ((__nothrow__ , __leaf__)) sprintf (char *__restrict __s, const char *__restrict __fmt, ...) { return __builtin___sprintf_chk (__s, 2 - 1, __builtin_object_size (__s, 2 > 1), __fmt, __builtin_va_arg_pack ()); } char number[sizeof "999999"]; int somerandom (void); void Foo (void) { int i = somerandom (); if (! (0 <= i)) __builtin_unreachable (); if (! (0 <= i && i <= 999999)) __builtin_unreachable (); sprintf (number, "%d", i); } $ gcc -Wformat-overflow -O2 -S v.i v.i: In function ‘Foo’: v.i:17:21: warning: ‘%d’ directive writing between 1 and 10 bytes into a region of size 7 [-Wformat-overflow=] sprintf (number, "%d", i); ^~ v.i:17:20: note: directive argument in the range [0, 2147483647] sprintf (number, "%d", i); ^~~~ v.i:4:10: note: ‘__builtin___sprintf_chk’ output between 2 and 11 bytes into a destination of size 7 return __builtin___sprintf_chk (__s, 2 - 1, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __builtin_object_size (__s, 2 > 1), __fmt, __builtin_va_arg_pack ()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~