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,

Reply via email to