https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78586
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Even for TYPE_PRECISION (dirtype) == TYPE_PRECISION (argtype), if one is signed and the other is unsigned, are you sure that for VR_RANGE we do the right thing? Again, should be backed out by sufficient testsuite coverage. E.g. consider: __attribute__((noinline, noclone)) int foo (unsigned int x) { if (x < 64 || x > 2U * __INT_MAX__ - 10) return -1; char buf[4]; return __builtin_sprintf (buf, "%d", x + 1); } Here we don't warn with -O2 -W -Wall, but if I change buf[4] to buf[1], I get: warning: ā%dā directive writing between 2 and 3 bytes into a region of size 1 and note: directive argument in the range [65u, 4294967285u] But the directive is not writing in between 2 and 3 bytes, it is a number in the range [65, INT_MAX] or [INT_MIN, -11], i.e. ~[-10, 64], thus it needs in between 2 and 11 bytes. For the warning that is a missed-warning case, but it wouldn't surprise me if you couldn't construct a similar testcase perhaps with sign -> unsigned or something similar (and octal or decimal, etc., many options) where you'd be warning even on something that is safe.