On Mon, Mar 27, 2017 at 7:30 PM, Marek Polacek <pola...@redhat.com> wrote:
> The code in fold_comparison calls save_expr on an expression and then tries to
> set a location of the expression.  But since save_expr calls fold, it can
> produce an integer constant, so we must be more careful when setting its
> location.  In this case we had
>
>   (int) a > 646
>
> where 'a' is signed char so we fold it to 0.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk/6?
>
> 2017-03-27  Marek Polacek  <pola...@redhat.com>
>
>         PR sanitizer/80067
>         * fold-const.c (fold_comparison): Use protected_set_expr_location
>         instead of SET_EXPR_LOCATION.
>
>         * c-c++-common/ubsan/shift-10.c: New test.
>
> diff --git gcc/fold-const.c gcc/fold-const.c
> index 1a9a264..6db16b5 100644
> --- gcc/fold-const.c
> +++ gcc/fold-const.c
> @@ -8704,7 +8704,7 @@ fold_comparison (location_t loc, enum tree_code code, 
> tree type,
>               if (save_p)
>                 {
>                   tem = save_expr (build2 (code, type, cval1, cval2));
> -                 SET_EXPR_LOCATION (tem, loc);
> +                 protected_set_expr_location (tem, loc);

I believe using

   tem = save_expr (build2_loc (loc, code, type, cval1, cval2));

would have worked just fine.  save_expr uses the exprs location (if available).

But the patch is ok as well.

Richard.

>                   return tem;
>                 }
>               return fold_build2_loc (loc, code, type, cval1, cval2);
> diff --git gcc/testsuite/c-c++-common/ubsan/shift-10.c 
> gcc/testsuite/c-c++-common/ubsan/shift-10.c
> index e69de29..9202fcc 100644
> --- gcc/testsuite/c-c++-common/ubsan/shift-10.c
> +++ gcc/testsuite/c-c++-common/ubsan/shift-10.c
> @@ -0,0 +1,10 @@
> +/* PR sanitizer/80067 */
> +/* { dg-do compile } */
> +/* { dg-options "-fsanitize=shift" } */
> +
> +extern signed char a;
> +void
> +foo ()
> +{
> +  0 << ((647 > a) - 1);
> +}
>
>         Marek

Reply via email to