[PATCH] Fix another fold-const.c type bug (PR sanitizer/80403)
Richard Biener
rguenther@suse.de
Wed Apr 12 17:43:00 GMT 2017
On April 12, 2017 6:12:57 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>Similarly to PR80349, we have other spots where we don't get the
>types right. opN are the original args, argN is the same after
>STRIP_NOPS, so when we want to have type of type, we should use
>opN rather than argN (opN is less expensive variant to fold_convert
>argN to type).
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK
Richard.
>2017-04-12 Jakub Jelinek <jakub@redhat.com>
>
> PR sanitizer/80403
> PR sanitizer/80404
> PR sanitizer/80405
> * fold-const.c (fold_ternary_loc): Use op1 instead of arg1 as argument
> to fold_build2_loc. Convert TREE_OPERAND (tem, 0) to type. Use
> op0 instead of fold_convert_loc (loc, type, arg0).
>
> * g++.dg/ubsan/pr80403.C: New test.
> * g++.dg/ubsan/pr80404.C: New test.
> * g++.dg/ubsan/pr80405.C: New test.
>
>--- gcc/fold-const.c.jj 2017-04-12 07:20:42.000000000 +0200
>+++ gcc/fold-const.c 2017-04-12 08:59:09.044260961 +0200
>@@ -11508,10 +11508,12 @@ fold_ternary_loc (location_t loc, enum t
> STRIP_NOPS (tem);
> if (TREE_CODE (tem) == RSHIFT_EXPR
> && tree_fits_uhwi_p (TREE_OPERAND (tem, 1))
>- && (unsigned HOST_WIDE_INT) tree_log2 (arg1) ==
>- tree_to_uhwi (TREE_OPERAND (tem, 1)))
>+ && (unsigned HOST_WIDE_INT) tree_log2 (arg1)
>+ == tree_to_uhwi (TREE_OPERAND (tem, 1)))
> return fold_build2_loc (loc, BIT_AND_EXPR, type,
>- TREE_OPERAND (tem, 0), arg1);
>+ fold_convert_loc (loc, type,
>+ TREE_OPERAND (tem, 0)),
>+ op1);
> }
>
> /* A & N ? N : 0 is simply A & N if N is a power of two. This
>@@ -11542,7 +11544,7 @@ fold_ternary_loc (location_t loc, enum t
> && (code == VEC_COND_EXPR || !VECTOR_TYPE_P (type)))
> return fold_build2_loc (loc, code == VEC_COND_EXPR ? BIT_AND_EXPR
> : TRUTH_ANDIF_EXPR,
>- type, fold_convert_loc (loc, type, arg0), arg1);
>+ type, op0, op1);
>
> /* Convert A ? B : 1 into !A || B if A and B are truth values. */
>if (code == VEC_COND_EXPR ? integer_all_onesp (op2) : integer_onep
>(op2)
>@@ -11558,7 +11560,7 @@ fold_ternary_loc (location_t loc, enum t
> ? BIT_IOR_EXPR
> : TRUTH_ORIF_EXPR,
> type, fold_convert_loc (loc, type, tem),
>- arg1);
>+ op1);
> }
>
> /* Convert A ? 0 : B into !A && B if A and B are truth values. */
>--- gcc/testsuite/g++.dg/ubsan/pr80403.C.jj 2017-04-12
>08:52:20.954465589 +0200
>+++ gcc/testsuite/g++.dg/ubsan/pr80403.C 2017-04-12 08:52:00.000000000
>+0200
>@@ -0,0 +1,11 @@
>+// PR sanitizer/80403
>+// { dg-do compile }
>+// { dg-options "-fsanitize=undefined" }
>+
>+unsigned
>+foo ()
>+{
>+ unsigned a = (unsigned) (!(6044238 >> 0) >= (0 < 0)) % 0; // {
>dg-warning "division by zero" }
>+ unsigned b = (unsigned) (!(6044238 >> 0) >= (0 < 0)) / 0; // {
>dg-warning "division by zero" }
>+ return a + b;
>+}
>--- gcc/testsuite/g++.dg/ubsan/pr80404.C.jj 2017-04-12
>09:08:43.497014011 +0200
>+++ gcc/testsuite/g++.dg/ubsan/pr80404.C 2017-04-12 09:07:26.000000000
>+0200
>@@ -0,0 +1,12 @@
>+// PR sanitizer/80404
>+// { dg-do compile }
>+// { dg-options "-fsanitize=undefined" }
>+
>+extern short v;
>+
>+unsigned
>+foo ()
>+{
>+ unsigned a = (0 < 0 >= (0 >= 0)) / (unsigned) v;
>+ return a;
>+}
>--- gcc/testsuite/g++.dg/ubsan/pr80405.C.jj 2017-04-12
>09:08:46.663973725 +0200
>+++ gcc/testsuite/g++.dg/ubsan/pr80405.C 2017-04-12 09:07:53.000000000
>+0200
>@@ -0,0 +1,11 @@
>+// PR sanitizer/80405
>+// { dg-do compile }
>+// { dg-options "-fsanitize=undefined" }
>+
>+extern unsigned int v, w;
>+
>+void
>+foo ()
>+{
>+ w = (!~0 >= (unsigned) (0 < 0)) << v;
>+}
>
>
> Jakub
More information about the Gcc-patches
mailing list