diff mbox

Fix another fold-const.c type bug (PR sanitizer/80403)

Message ID 20170412161257.GY1809@tucnak
State New
Headers show

Commit Message

Jakub Jelinek April 12, 2017, 4:12 p.m. UTC
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?

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.



	Jakub

Comments

Richard Biener April 12, 2017, 5:43 p.m. UTC | #1
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
diff mbox

Patch

--- 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;
+}