2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org>
authortkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Apr 2014 10:48:56 +0000 (10:48 +0000)
committertkoenig <tkoenig@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 27 Apr 2014 10:48:56 +0000 (10:48 +0000)
PR fortran/59604
PR fortran/58003
* 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-27  Thomas Koenig  <tkoenig@gcc.gnu.org>

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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209836 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/fortran/ChangeLog
gcc/fortran/arith.c
gcc/fortran/gfortran.h
gcc/fortran/simplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/no_range_check_3.f90 [new file with mode: 0644]

index 427c9b1..5cf2513 100644 (file)
@@ -1,3 +1,23 @@
+2014-03-27  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/59604
+       PR fortran/58003
+       * 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-04-22  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/60881
index 053cf76..a05fa49 100644 (file)
@@ -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 14c202d..f0eed80 100644 (file)
@@ -3022,4 +3022,8 @@ typedef int (*walk_expr_fn_t) (gfc_expr **, int *, void *);
 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 96d0f21..1b6cd5b 100644 (file)
@@ -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, gfc_expr *shiftarg,
       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_expr *z)
 
   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 char *name,
        }
     }
 
-  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_expr *sz)
        }
     }
 
-  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_arg)
   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_arg)
   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;
 }
index 7d01d44..ba21fed 100644 (file)
@@ -1,3 +1,9 @@
+2014-03-27  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/59604
+       PR fortran/58003
+       * gfortran.dg/no_range_check_3.f90:  New test.
+
 2014-04-26  Jerry DeLisle  <jvdelisle@gcc.gnu>
 
        PR libfortran/52539
diff --git a/gcc/testsuite/gfortran.dg/no_range_check_3.f90 b/gcc/testsuite/gfortran.dg/no_range_check_3.f90
new file mode 100644 (file)
index 0000000..24223af
--- /dev/null
@@ -0,0 +1,12 @@
+! { dg-do run }
+! { dg-options "-fno-range-check" }
+program test
+  integer :: i
+  i = int(z'FFFFFFFF',kind(i))
+  if (i /= -1) call abort
+  if (int(z'FFFFFFFF',kind(i)) /= -1) call abort
+
+  if (popcnt(int(z'0F00F00080000001',8)) /= 10) call abort
+  if (popcnt(int(z'800F0001',4)) /= 6) call abort
+
+end program test