diff mbox

Fix fold_binary_loc BIT_IOR_EXPR folding (PR sanitizer/80349)

Message ID 20170411205410.GX1809@tucnak
State New
Headers show

Commit Message

Jakub Jelinek April 11, 2017, 8:54 p.m. UTC
Hi!

This is another case where we miss needed folding from argN or their
arguments to the expected expression type (type has to be compatible
with opN's type, but argN is after STRIP_NOPS).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-04-11  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/80349
	* fold-const.c (fold_binary_loc) <case BIT_IOR_EXPR>: Convert arg0's
	first argument to type.

	* g++.dg/ubsan/pr80349.C: New test.


	Jakub

Comments

Richard Biener April 12, 2017, 5:36 a.m. UTC | #1
On April 11, 2017 10:54:10 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>This is another case where we miss needed folding from argN or their
>arguments to the expected expression type (type has to be compatible
>with opN's type, but argN is after STRIP_NOPS).
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

>2017-04-11  Jakub Jelinek  <jakub@redhat.com>
>
>	PR sanitizer/80349
>	* fold-const.c (fold_binary_loc) <case BIT_IOR_EXPR>: Convert arg0's
>	first argument to type.
>
>	* g++.dg/ubsan/pr80349.C: New test.
>
>--- gcc/fold-const.c.jj	2017-04-10 22:27:00.000000000 +0200
>+++ gcc/fold-const.c	2017-04-11 20:07:02.459839450 +0200
>@@ -9916,12 +9916,12 @@ fold_binary_loc (location_t loc,
> 	    }
> 
> 	  if (c3 != c1)
>-	    return fold_build2_loc (loc, BIT_IOR_EXPR, type,
>-				    fold_build2_loc (loc, BIT_AND_EXPR, type,
>-						     TREE_OPERAND (arg0, 0),
>-						     wide_int_to_tree (type,
>-								       c3)),
>-				    arg1);
>+	    {
>+	      tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
>+	      tem = fold_build2_loc (loc, BIT_AND_EXPR, type, tem,
>+				     wide_int_to_tree (type, c3));
>+	      return fold_build2_loc (loc, BIT_IOR_EXPR, type, tem, arg1);
>+	    }
> 	}
> 
>       /* See if this can be simplified into a rotate first.  If that
>--- gcc/testsuite/g++.dg/ubsan/pr80349.C.jj	2017-04-11
>20:29:10.154344673 +0200
>+++ gcc/testsuite/g++.dg/ubsan/pr80349.C	2017-04-11 20:28:38.000000000
>+0200
>@@ -0,0 +1,11 @@
>+// PR sanitizer/80349
>+// { dg-do compile }
>+// { dg-options "-fsanitize=undefined" }
>+
>+extern const long long int v;
>+
>+void
>+foo ()
>+{
>+  (int)((v & 50 | 051UL) << 0) << 0;
>+}
>
>	Jakub
diff mbox

Patch

--- gcc/fold-const.c.jj	2017-04-10 22:27:00.000000000 +0200
+++ gcc/fold-const.c	2017-04-11 20:07:02.459839450 +0200
@@ -9916,12 +9916,12 @@  fold_binary_loc (location_t loc,
 	    }
 
 	  if (c3 != c1)
-	    return fold_build2_loc (loc, BIT_IOR_EXPR, type,
-				    fold_build2_loc (loc, BIT_AND_EXPR, type,
-						     TREE_OPERAND (arg0, 0),
-						     wide_int_to_tree (type,
-								       c3)),
-				    arg1);
+	    {
+	      tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
+	      tem = fold_build2_loc (loc, BIT_AND_EXPR, type, tem,
+				     wide_int_to_tree (type, c3));
+	      return fold_build2_loc (loc, BIT_IOR_EXPR, type, tem, arg1);
+	    }
 	}
 
       /* See if this can be simplified into a rotate first.  If that
--- gcc/testsuite/g++.dg/ubsan/pr80349.C.jj	2017-04-11 20:29:10.154344673 +0200
+++ gcc/testsuite/g++.dg/ubsan/pr80349.C	2017-04-11 20:28:38.000000000 +0200
@@ -0,0 +1,11 @@ 
+// PR sanitizer/80349
+// { dg-do compile }
+// { dg-options "-fsanitize=undefined" }
+
+extern const long long int v;
+
+void
+foo ()
+{
+  (int)((v & 50 | 051UL) << 0) << 0;
+}