https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82072
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Marek Polacek from comment #6) > This should fix the two issues above: > > --- a/gcc/convert.c > +++ b/gcc/convert.c > @@ -434,6 +434,12 @@ do_narrow (location_t loc, > typex = lang_hooks.types.type_for_size (TYPE_PRECISION (typex), > TYPE_UNSIGNED (typex)); > > + /* The type demotion below might cause doing unsigned arithmetic > + instead of signed, and thus hide overflow bugs. */ > + if (!TYPE_UNSIGNED (typex) > + && sanitize_flags_p (SANITIZE_SI_OVERFLOW)) > + return NULL_TREE; > + Shouldn't we check ex_form here too, and only punt if it is an operation problematic for the particular ubsan sanitization? There is no reason why we can't e.g. narrow BIT_AND_EXPR. Have you checked the shift and division cases? > /* But now perhaps TYPEX is as wide as INPREC. > In that case, do nothing special here. > (Otherwise would recurse infinitely in convert. */ > @@ -895,7 +901,12 @@ convert_to_integer_1 (tree type, tree expr, bool dofold) > TYPE_UNSIGNED (typex)); > > if (!TYPE_UNSIGNED (typex)) > - typex = unsigned_type_for (typex); > + { > + /* Using unsigned arithmetic may hide overflow bugs. */ > + if (sanitize_flags_p (SANITIZE_SI_OVERFLOW)) > + break; > + typex = unsigned_type_for (typex); > + } > return convert (type, > fold_build1 (ex_form, typex, > convert (typex,