Fix UB in round_up_loc (PR c/67338)

Submitted by Jakub Jelinek on March 20, 2017, 9:05 p.m.

Details

Message ID 20170320210520.GM11094@tucnak
State New
Headers show

Commit Message

Jakub Jelinek March 20, 2017, 9:05 p.m.
Hi!

divisor is unsigned int parameter, if it is 0x80000000, we invoke UB.
val is wide_int, so (int) -divisor achieves the same result without UB.

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

2017-03-20  Jakub Jelinek  <jakub@redhat.com>

	PR c/67338
	* fold-const.c (round_up_loc): Negate divisor in unsigned type to
	avoid UB.

	* gcc.dg/pr67338.c: New test.


	Jakub

Comments

Richard Guenther March 21, 2017, 8:08 a.m.
On Mon, 20 Mar 2017, Jakub Jelinek wrote:

> Hi!
> 
> divisor is unsigned int parameter, if it is 0x80000000, we invoke UB.
> val is wide_int, so (int) -divisor achieves the same result without UB.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2017-03-20  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c/67338
> 	* fold-const.c (round_up_loc): Negate divisor in unsigned type to
> 	avoid UB.
> 
> 	* gcc.dg/pr67338.c: New test.
> 
> --- gcc/fold-const.c.jj	2017-03-16 17:18:25.000000000 +0100
> +++ gcc/fold-const.c	2017-03-20 07:53:53.680953740 +0100
> @@ -14250,7 +14250,7 @@ round_up_loc (location_t loc, tree value
>  
>  	  overflow_p = TREE_OVERFLOW (value);
>  	  val += divisor - 1;
> -	  val &= - (int) divisor;
> +	  val &= (int) -divisor;
>  	  if (val == 0)
>  	    overflow_p = true;
>  
> --- gcc/testsuite/gcc.dg/pr67338.c.jj	2017-03-20 09:09:05.489002468 +0100
> +++ gcc/testsuite/gcc.dg/pr67338.c	2017-03-20 09:08:54.000000000 +0100
> @@ -0,0 +1,4 @@
> +/* PR c/67338 */
> +/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
> +
> +struct S { __attribute__((aligned (1 << 28))) double a; };
> 
> 	Jakub
> 
>

Patch hide | download patch | download mbox

--- gcc/fold-const.c.jj	2017-03-16 17:18:25.000000000 +0100
+++ gcc/fold-const.c	2017-03-20 07:53:53.680953740 +0100
@@ -14250,7 +14250,7 @@  round_up_loc (location_t loc, tree value
 
 	  overflow_p = TREE_OVERFLOW (value);
 	  val += divisor - 1;
-	  val &= - (int) divisor;
+	  val &= (int) -divisor;
 	  if (val == 0)
 	    overflow_p = true;
 
--- gcc/testsuite/gcc.dg/pr67338.c.jj	2017-03-20 09:09:05.489002468 +0100
+++ gcc/testsuite/gcc.dg/pr67338.c	2017-03-20 09:08:54.000000000 +0100
@@ -0,0 +1,4 @@ 
+/* PR c/67338 */
+/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
+
+struct S { __attribute__((aligned (1 << 28))) double a; };