https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89161
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |diagnostic Status|UNCONFIRMED |NEW Last reconfirmed| |2019-02-02 CC| |msebor at gcc dot gnu.org Blocks| |85741 Ever confirmed|0 |1 Known to fail| |7.3.0, 8.2.0, 9.0 --- Comment #1 from Martin Sebor <msebor at gcc dot gnu.org> --- I can confirm the warning and agree that GCC could in theory figure out that the result is between 0 and 9 but it currently doesn't do that. With the optimization implemented the warning would go away. Note that there are limitations as how far GCC can go in determining the values or ranges of non-constant expressions, and warnings that rely on these abilities (i.e., flow-based warnings) are unavoidably imprecise. This is documented in the manual which says about -Wformat-overflow: Warn about calls to formatted input/output functions such as sprintf and vsprintf that might overflow the destination buffer. When the exact number of bytes written by a format directive cannot be determined at compile-time it is estimated based on heuristics that depend on the level argument and on optimization. A test case for the missing optimization is: void f (unsigned short a, unsigned short b) { if (a && a < b) { int x = (10 * a) / b; if (x < 0 || 9 < x) __builtin_abort (); } } Compiling it with the -fdump-tree-vrp=/dev/stdout option shows that range in which x is computed to be by VRP is: x_10: int [0, 655350] ... <bb 3> [local count: 536870913]: _4 = (int) a_8(D); _5 = _4 * 10; _6 = (int) b_9(D); x_10 = _5 / _6; if (x_10 > 9) goto <bb 4>; [0.00%] else goto <bb 5>; [100.00%] <bb 4> [count: 0]: __builtin_abort (); Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85741 [Bug 85741] [meta-bug] bogus/missing -Wformat-overflow