Commit 025e5647 by Richard Sandiford Committed by Richard Sandiford

re PR fortran/63427 (hwint.h:250:29: runtime error: shift exponent 64 is too…

re PR fortran/63427 (hwint.h:250:29: runtime error: shift exponent 64 is too large for 64-bit type 'long int')

gcc/
	PR fortran/63427
	* wide-int.cc (wi::from_mpz): Cope with unwrapped values that are
	too big for a wide_int.  Implement missing wrapping operation.

gcc/testsuite/
	PR fortran/63427
	* gfortran.dg/integer_exponentiation_6.F90: New test.

From-SVN: r220921
parent 8628d6e6
2015-02-23 Richard Sandiford <richard.sandiford@arm.com>
PR fortran/63427
* wide-int.cc (wi::from_mpz): Cope with unwrapped values that are
too big for a wide_int. Implement missing wrapping operation.
2015-02-23 Oleg Endo <olegendo@gcc.gnu.org> 2015-02-23 Oleg Endo <olegendo@gcc.gnu.org>
PR target/65163 PR target/65163
......
2015-02-23 Richard Sandiford <richard.sandiford@arm.com>
PR fortran/63427
* gfortran.dg/integer_exponentiation_6.F90: New test.
2015-02-23 Martin Sebor <msebor@redhat.com> 2015-02-23 Martin Sebor <msebor@redhat.com>
PR target/65109 PR target/65109
......
! { dg-options "-fno-range-check" }
program test
write (*), (2_8 ** 64009999_8) / 2
end program test
...@@ -237,7 +237,7 @@ wide_int ...@@ -237,7 +237,7 @@ wide_int
wi::from_mpz (const_tree type, mpz_t x, bool wrap) wi::from_mpz (const_tree type, mpz_t x, bool wrap)
{ {
size_t count, numb; size_t count, numb;
int prec = TYPE_PRECISION (type); unsigned int prec = TYPE_PRECISION (type);
wide_int res = wide_int::create (prec); wide_int res = wide_int::create (prec);
if (!wrap) if (!wrap)
...@@ -261,16 +261,28 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap) ...@@ -261,16 +261,28 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap)
for representing the value. The code to calculate count is for representing the value. The code to calculate count is
extracted from the GMP manual, section "Integer Import and Export": extracted from the GMP manual, section "Integer Import and Export":
http://gmplib.org/manual/Integer-Import-and-Export.html */ http://gmplib.org/manual/Integer-Import-and-Export.html */
numb = 8 * sizeof(HOST_WIDE_INT); numb = CHAR_BIT * sizeof (HOST_WIDE_INT);
count = (mpz_sizeinbase (x, 2) + numb - 1) / numb; count = (mpz_sizeinbase (x, 2) + numb - 1) / numb;
HOST_WIDE_INT *val = res.write_val (); HOST_WIDE_INT *val = res.write_val ();
mpz_export (val, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, x); /* Write directly to the wide_int storage if possible, otherwise leave
GMP to allocate the memory for us. It might be slightly more efficient
to use mpz_tdiv_r_2exp for the latter case, but the situation is
pathological and it seems safer to operate on the original mpz value
in all cases. */
void *valres = mpz_export (count <= WIDE_INT_MAX_ELTS ? val : 0,
&count, -1, sizeof (HOST_WIDE_INT), 0, 0, x);
if (count < 1) if (count < 1)
{ {
val[0] = 0; val[0] = 0;
count = 1; count = 1;
} }
res.set_len (count); count = MIN (count, BLOCKS_NEEDED (prec));
if (valres != val)
{
memcpy (val, valres, count * sizeof (HOST_WIDE_INT));
free (valres);
}
res.set_len (canonize (val, count, prec));
if (mpz_sgn (x) < 0) if (mpz_sgn (x) < 0)
res = -res; res = -res;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment