https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95141
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- So there's already (OVF) at ((long unsigned int) IA1 & 158(OVF)) & 1 but we only check 375 if (TREE_OVERFLOW_P (ret) 376 && !TREE_OVERFLOW_P (op0) 377 && !TREE_OVERFLOW_P (op1)) 378 overflow_warning (EXPR_LOC_OR_LOC (expr, input_location), ret, expr); which doesn't catch the pre-existing overflow on op0 which then propagates. The original overflow is introduced folding short 158 to signed char -98(OVF) via convert.c:do_narrow: 437 /* We should do away with all this once we have a proper 438 type promotion/demotion pass, see PR45397. */ 439 expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex, 440 convert (typex, arg0), 441 convert (typex, arg1)); specifically the convert (typex, arg1). Now TREE_OVERFLOW in general is quite a fragile thing, but it's tempting to adjust the overflow_warning guard for this case ... The do_narrow code also specifically looks for overflow cases that matter and does not perform narrowing then so clearing TREE_OVERFLOW there would also look reasonable. Thus like the following? Should be cheaper than adding walk_tree to the diagnostic guard. diff --git a/gcc/convert.c b/gcc/convert.c index 42509c518a9..ed00ded1a89 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -436,9 +436,16 @@ do_narrow (location_t loc, } /* We should do away with all this once we have a proper type promotion/demotion pass, see PR45397. */ + /* Above we checked for all cases where overflow matters, avoid + geneating overflowed constants here which otherwise propagate + and cause spurious warnings, see PR95141. */ + tree converted_arg1 = convert (typex, arg1); + if (TREE_OVERFLOW_P (converted_arg1) + && !TREE_OVERFLOW_P (arg1)) + converted_arg1 = drop_tree_overflow (converted_arg1); expr = maybe_fold_build2_loc (dofold, loc, ex_form, typex, convert (typex, arg0), - convert (typex, arg1)); + converted_arg1); return convert (type, expr); }