https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81908
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2017-08-21 CC| |msebor at gcc dot gnu.org Target Milestone|--- |8.0 Ever confirmed|0 |1 --- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> --- Probably caused by [/tmp/trunk/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_2.f90:33:0] # RANGE [-2147483648, 0] NONZERO 4294967292 _260 = ubound.2_35 * 4; [/tmp/trunk/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_2.f90:33:0] # RANGE ~[1, 2147483647] NONZERO 4294967292 _261 = (character(kind=4)) _260; ... __builtin_memcpy (_264, _272, _261); where the warning machinery simply doesn't consider the valid input _261 == 0. get_size_range runs into else if (wi::eq_p (wzero, min - 1)) { /* EXP is unsigned and not in the range [1, MAX]. That means it's either zero or greater than MAX. Even though 0 would normally be detected by -Walloc-zero set the range to [MAX, TYPE_MAX] so that when MAX is greater than the limit the whole range is diagnosed. */ min = max + 1; max = wmaxval; I totally detest this anti-range handling. It's completely bogus. For whatever reason it _does_ want to diagnose here. So - INVALID, working as designed?! The comment is wrong btw, EXP is in the range 0 U [max + 1, wmaxval]. 'MAX' is used inconsistently -- nothing is bigger than 'MAX' unless 'MAX' is maximum value that is positive when interpreted signed. But wmaxval is unsigned. Suggested patch: Index: gcc/calls.c =================================================================== --- gcc/calls.c (revision 251217) +++ gcc/calls.c (working copy) @@ -1327,7 +1327,8 @@ get_size_range (tree exp, tree range[2]) min = wzero; } } - else if (wi::eq_p (wzero, min - 1)) + else if (wi::eq_p (wzero, min - 1) + && wi::lts_p (max, wi::max_value (expprec, SIGNED))) { /* EXP is unsigned and not in the range [1, MAX]. That means it's either zero or greater than MAX. Even though 0 would that (for this sub-case of anit-range handling) tries to preserve anti-range ^ valid-size-range if not empty. I think that's a must to get false positives to a minimum.