This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix another fold-const.c type bug (PR sanitizer/80403)
- From: Richard Biener <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 12 Apr 2017 19:43:26 +0200
- Subject: Re: [PATCH] Fix another fold-const.c type bug (PR sanitizer/80403)
- Authentication-results: sourceware.org; auth=none
- References: <20170412161257.GY1809@tucnak>
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