diff mbox

[fortran] Fix PR 59604

Message ID 53499525.2060009@netcologne.de
State New
Headers show

Commit Message

Thomas Koenig April 12, 2014, 7:33 p.m. UTC
Hello world,

please find attached a patch for PR 59604.

The patch makes sure that, if -fno-range-check is specified,
using int on an overflowing boz constant yields the same
result for compile-time simplification and run-time
execution.

OK for trunk?

	Thomas

2014-03-12  Thomas Koenig  <tkoenig@gcc.gnu.org>

        PR fortran/59604
        * gfortran.h (gfc_convert_mpz_to_signed):  Add prototype.
        * arith.c (gfc_int2int):  Convert number to signed if
        arithmetic overflow is not checked.
        * simplify.c (convert_mpz_to_unsigned): Only trigger assert for
        size if range checking is in force.
        (convert_mpz_to_signed):  Make non-static, rename to
        (gfc_convert_mpz_to_signed).
        (simplify_dshift): Use gfc_convert_mpz_to_signed.
        (gfc_simplify_ibclr):  Likewise.
        (gfc_simplify_ibits):  Likewise.
        (gfc_simplify_ibset):  Likewise.
        (simplify_shift):  Likewise.
        (gfc_simplify_ishiftc):  Likewise.
        (gfc_simplify_maskr):  Likewise.
        (gfc_simplify_maskl):  Likewise.

2014-03-12  Thomas Koenig  <tkoenig@gcc.gnu.org>

        PR fortran/59604
        * gfortran.dg/no_range_check_3.f90:  New test.

Comments

Thomas Koenig April 25, 2014, 8:50 a.m. UTC | #1
OK for trunk?

Full patch at

http://gcc.gnu.org/ml/gcc-patches/2014-04/msg00616.html

> Hello world,
> 
> please find attached a patch for PR 59604.
> 
> The patch makes sure that, if -fno-range-check is specified,
> using int on an overflowing boz constant yields the same
> result for compile-time simplification and run-time
> execution.
> 
> OK for trunk?
> 
> 	Thomas
> 
> 2014-03-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
> 
>         PR fortran/59604
>         * gfortran.h (gfc_convert_mpz_to_signed):  Add prototype.
>         * arith.c (gfc_int2int):  Convert number to signed if
>         arithmetic overflow is not checked.
>         * simplify.c (convert_mpz_to_unsigned): Only trigger assert for
>         size if range checking is in force.
>         (convert_mpz_to_signed):  Make non-static, rename to
>         (gfc_convert_mpz_to_signed).
>         (simplify_dshift): Use gfc_convert_mpz_to_signed.
>         (gfc_simplify_ibclr):  Likewise.
>         (gfc_simplify_ibits):  Likewise.
>         (gfc_simplify_ibset):  Likewise.
>         (simplify_shift):  Likewise.
>         (gfc_simplify_ishiftc):  Likewise.
>         (gfc_simplify_maskr):  Likewise.
>         (gfc_simplify_maskl):  Likewise.
> 
> 2014-03-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
> 
>         PR fortran/59604
>         * gfortran.dg/no_range_check_3.f90:  New test.
>
Tobias Burnus April 26, 2014, 8:38 a.m. UTC | #2
Am 12.04.2014 21:33, schrieb Thomas Koenig:
> please find attached a patch for PR 59604.
>
> The patch makes sure that, if -fno-range-check is specified,
> using int on an overflowing boz constant yields the same
> result for compile-time simplification and run-time
> execution.
>
> OK for trunk?

Looks good to me. At a glance, it looks as if it also fixes the original 
bug 58003 - or is something still missing?

Tobias

> 2014-03-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
>
>          PR fortran/59604
>          * gfortran.h (gfc_convert_mpz_to_signed):  Add prototype.
>          * arith.c (gfc_int2int):  Convert number to signed if
>          arithmetic overflow is not checked.
>          * simplify.c (convert_mpz_to_unsigned): Only trigger assert for
>          size if range checking is in force.
>          (convert_mpz_to_signed):  Make non-static, rename to
>          (gfc_convert_mpz_to_signed).
>          (simplify_dshift): Use gfc_convert_mpz_to_signed.
>          (gfc_simplify_ibclr):  Likewise.
>          (gfc_simplify_ibits):  Likewise.
>          (gfc_simplify_ibset):  Likewise.
>          (simplify_shift):  Likewise.
>          (gfc_simplify_ishiftc):  Likewise.
>          (gfc_simplify_maskr):  Likewise.
>          (gfc_simplify_maskl):  Likewise.
>
> 2014-03-12  Thomas Koenig  <tkoenig@gcc.gnu.org>
>
>          PR fortran/59604
>          * gfortran.dg/no_range_check_3.f90:  New test.
>
Thomas Koenig April 27, 2014, 10:50 a.m. UTC | #3
Hi Tobias,

> Am 12.04.2014 21:33, schrieb Thomas Koenig:
>> please find attached a patch for PR 59604.
>>
>> The patch makes sure that, if -fno-range-check is specified,
>> using int on an overflowing boz constant yields the same
>> result for compile-time simplification and run-time
>> execution.
>>
>> OK for trunk?
> 
> Looks good to me. At a glance, it looks as if it also fixes the original
> bug 58003 - or is something still missing?

You're right - the original PR is also fixed.

I have included a modification of the original test case,
and mentioned PR 58003 in the ChangeLog.

Thanks!

	Thomas
diff mbox

Patch

Index: gfortran.h
===================================================================
--- gfortran.h	(Revision 206202)
+++ gfortran.h	(Arbeitskopie)
@@ -3018,4 +3018,8 @@  typedef int (*walk_expr_fn_t) (gfc_expr **, int *,
 int gfc_expr_walker (gfc_expr **, walk_expr_fn_t, void *);
 int gfc_code_walker (gfc_code **, walk_code_fn_t, walk_expr_fn_t, void *);
 
+/* simplify.c */
+
+void gfc_convert_mpz_to_signed (mpz_t, int);
+
 #endif /* GCC_GFORTRAN_H  */
Index: arith.c
===================================================================
--- arith.c	(Revision 206202)
+++ arith.c	(Arbeitskopie)
@@ -1976,6 +1976,17 @@  gfc_int2int (gfc_expr *src, int kind)
 	}
     }
 
+  /*  If we do not trap numeric overflow, we need to convert the number to
+      signed, throwing away high-order bits if necessary.  */
+  if (gfc_option.flag_range_check == 0)
+    {
+      int k;
+
+      k = gfc_validate_kind (BT_INTEGER, kind, false);
+      gfc_convert_mpz_to_signed (result->value.integer,
+				 gfc_integer_kinds[k].bit_size);
+    }
+
   return result;
 }
 
Index: simplify.c
===================================================================
--- simplify.c	(Revision 206202)
+++ simplify.c	(Arbeitskopie)
@@ -151,8 +151,10 @@  convert_mpz_to_unsigned (mpz_t x, int bitsize)
 
   if (mpz_sgn (x) < 0)
     {
-      /* Confirm that no bits above the signed range are unset.  */
-      gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX);
+      /* Confirm that no bits above the signed range are unset if we
+	 are doing range checking.  */
+      if (gfc_option.flag_range_check != 0)
+	gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX);
 
       mpz_init_set_ui (mask, 1);
       mpz_mul_2exp (mask, mask, bitsize);
@@ -175,13 +177,15 @@  convert_mpz_to_unsigned (mpz_t x, int bitsize)
    If the bitsize-1 bit is set, this is taken as a sign bit and
    the number is converted to the corresponding negative number.  */
 
-static void
-convert_mpz_to_signed (mpz_t x, int bitsize)
+void
+gfc_convert_mpz_to_signed (mpz_t x, int bitsize)
 {
   mpz_t mask;
 
-  /* Confirm that no bits above the unsigned range are set.  */
-  gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX);
+  /* Confirm that no bits above the unsigned range are set if we are
+     doing range checking.  */
+  if (gfc_option.flag_range_check != 0)
+    gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX);
 
   if (mpz_tstbit (x, bitsize - 1) == 1)
     {
@@ -1943,7 +1947,7 @@  simplify_dshift (gfc_expr *arg1, gfc_expr *arg2, g
       mpz_setbit (result->value.integer, shift + i);
 
   /* Convert to a signed value.  */
-  convert_mpz_to_signed (result->value.integer, size);
+  gfc_convert_mpz_to_signed (result->value.integer, size);
 
   return result;
 }
@@ -2561,7 +2565,7 @@  gfc_simplify_ibclr (gfc_expr *x, gfc_expr *y)
 
   mpz_clrbit (result->value.integer, pos);
 
-  convert_mpz_to_signed (result->value.integer,
+  gfc_convert_mpz_to_signed (result->value.integer,
 			 gfc_integer_kinds[k].bit_size);
 
   return result;
@@ -2619,7 +2623,7 @@  gfc_simplify_ibits (gfc_expr *x, gfc_expr *y, gfc_
 
   free (bits);
 
-  convert_mpz_to_signed (result->value.integer,
+  gfc_convert_mpz_to_signed (result->value.integer,
 			 gfc_integer_kinds[k].bit_size);
 
   return result;
@@ -2646,7 +2650,7 @@  gfc_simplify_ibset (gfc_expr *x, gfc_expr *y)
 
   mpz_setbit (result->value.integer, pos);
 
-  convert_mpz_to_signed (result->value.integer,
+  gfc_convert_mpz_to_signed (result->value.integer,
 			 gfc_integer_kinds[k].bit_size);
 
   return result;
@@ -3093,7 +3097,7 @@  simplify_shift (gfc_expr *e, gfc_expr *s, const ch
 	}
     }
 
-  convert_mpz_to_signed (result->value.integer, bitsize);
+  gfc_convert_mpz_to_signed (result->value.integer, bitsize);
   free (bits);
 
   return result;
@@ -3234,7 +3238,7 @@  gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc
 	}
     }
 
-  convert_mpz_to_signed (result->value.integer, isize);
+  gfc_convert_mpz_to_signed (result->value.integer, isize);
 
   free (bits);
   return result;
@@ -3954,7 +3958,7 @@  gfc_simplify_maskr (gfc_expr *i, gfc_expr *kind_ar
   mpz_mul_2exp (result->value.integer, result->value.integer, arg);
   mpz_sub_ui (result->value.integer, result->value.integer, 1);
 
-  convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
+  gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
 
   return result;
 }
@@ -3990,7 +3994,7 @@  gfc_simplify_maskl (gfc_expr *i, gfc_expr *kind_ar
   mpz_sub (result->value.integer, z, result->value.integer);
   mpz_clear (z);
 
-  convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
+  gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
 
   return result;
 }