https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81908
--- Comment #3 from Martin Sebor <msebor at gcc dot gnu.org> --- (In reply to Richard Biener from comment #1) The code was originally designed for -Walloc-size-larger-than and does the right thing for that warning. The range I see is _248: ~[1, 2147483647] __builtin_memcpy (_251, _259, _248); leaving 0 as the only valid value less than SIZE_MAX / 2 in ILP32. Zero is not really a valid allocation size so the code excludes it. But the code is also used for -Wstringop-overflow and the same logic doesn't apply equally well there. The warning does suggest that the memcpy could be eliminated, so as in most instances of it, the true root cause is really a missed optimization opportunity. In fact, this whole block must be unreachable because if it were executed it would either attempt to allocate more than SIZE_MAX / 2 bytes (which would fail) or allocate and write past the end of the 1-byte block: <bb 46> [0.43%] [count: INV]: vect_cst__246 = { -1, 265, 1, 1 }; _247 = ubound.2_35 * 4; _248 = (character(kind=4)) _247; // _248 is ~[1, 2147483647] _249 = MAX_EXPR <_248, 1>; // _249 must be 1 _251 = __builtin_malloc (_249); // _251 = malloc(1) __builtin_memcpy (_251, _259, _248); // no-op MEM[(struct grid_index_region *)&D.3501] = _251; MEM[(struct grid_index_region *)&D.3501 + 4B] = { -1, 265, 1, 1 }; // invalid/write-past-end MEM[(struct grid_index_region *)&D.3501 + 20B] = ubound.2_35; // invalid/write-past-end (In reply to Richard Biener from comment #1) get_size_range() sets the RANGE[] array to the unsigned bounds of the range of sizes. It can't set RANGE[0] > RANGE[1]. For example, the following must not be diagnosed but is with the suggested cleanup in comment #2. There may be a way to clean up the code but the suggested patch is not sufficient (it causes test suite regressions). void __attribute__ ((alloc_size (1))) f (unsigned long); void g (int n) { if (n < -9 || 9 < n) n = -9; f (n); }