https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79123
--- Comment #2 from Aldy Hernandez <aldyh at gcc dot gnu.org> --- [Just thinking out loud here.] Yeah. There's no correct range information available. For the argument to alloca we have: # RANGE ~[2305843009213693952, 16140901064495857663] n_9 = (long unsigned int) _4; if (n_9 <= 104) goto <bb 3>; [36.64%] else goto <bb 5>; [63.36%] <bb 5> [63.36%]: goto <bb 4>; [100.00%] <bb 3> [36.64%]: _5 = __builtin_alloca (n_9); And the anti range of ~[2305843009213693952, 16140901064495857663] can hold a value that is greater than 100 because it is essentially: (gdb) p/x 2305843009213693952-1 $4 = 0x1fffffffffffffff [0..0x1fffffffffffffff] and the union of whatever comes after 16140901064495857663. We do a horrible job dealing with VR_ANTI_RANGE's. As you point out, we're basically punting on an VR_ANTI_RANGE and ignoring that the casted result (n_9) has a bound later on: else if (range_type == VR_ANTI_RANGE) { // There may be some wrapping around going on. Catch it // with this heuristic. Hopefully, this VR_ANTI_RANGE // nonsense will go away, and we won't have to catch the // sign conversion problems with this crap. if (cast_from_signed_p (len, invalid_casted_type)) return alloca_type_and_limit (ALLOCA_CAST_FROM_SIGNED); } The above code was there to handle simple cases like: int n; ... if (n < 2000) { p = __builtin_alloca (n); f (p); } where we have a VR_ANTI_RANGE leading to a cast <bb 3> [36.64%]: # RANGE ~[2000, 18446744071562067967] _1 = (long unsigned int) n_3(D); p_6 = __builtin_alloca (_1); ...but the casted result (_1) has no known bound so this can be diagnosed. What we should do is somehow realize that in the original testcase, the casted result has a known bound, and perhaps punt down to the code that checks the BB's leading up to the alloca use: // If we couldn't find anything, try a few heuristics for things we // can easily determine. Check these misc cases but only accept // them if all predecessors have a known bound. Oh that we had better range info...