Commit efa591c5 by Francois-Xavier Coudert Committed by François-Xavier Coudert

re PR fortran/31262 (-fno-range-check with large integer values triggers ICE)

	PR fortran/31262

	* trans-const.c (gfc_conv_mpz_to_tree): Allow integer constants
	larger than twice the width of a HOST_WIDE_INT.

	* gfortran.dg/no_range_check_1.f90: New test.

From-SVN: r123136
parent ac294f0b
2007-03-22 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/31262
* trans-const.c (gfc_conv_mpz_to_tree): Allow integer constants
larger than twice the width of a HOST_WIDE_INT.
2006-03-22 Paul Thomas <pault@gcc.gnu.org> 2006-03-22 Paul Thomas <pault@gcc.gnu.org>
PR fortran/31193 PR fortran/31193
......
...@@ -165,23 +165,33 @@ gfc_conv_mpz_to_tree (mpz_t i, int kind) ...@@ -165,23 +165,33 @@ gfc_conv_mpz_to_tree (mpz_t i, int kind)
} }
else else
{ {
unsigned HOST_WIDE_INT words[2]; unsigned HOST_WIDE_INT *words;
size_t count; size_t count, numb;
/* Determine the number of unsigned HOST_WIDE_INT that are required
for represent the value. The code to calculate count is
extracted from the GMP manual, section "Integer Import and Export":
http://gmplib.org/manual/Integer-Import-and-Export.html */
numb = 8*sizeof(HOST_WIDE_INT);
count = (mpz_sizeinbase (i, 2) + numb-1) / numb;
if (count < 2)
count = 2;
words = (unsigned HOST_WIDE_INT *) alloca (count * sizeof(HOST_WIDE_INT));
/* Since we know that the value is not zero (mpz_fits_slong_p), /* Since we know that the value is not zero (mpz_fits_slong_p),
we know that at least one word will be written, but we don't know we know that at least one word will be written, but we don't know
about the second. It's quicker to zero the second word before about the second. It's quicker to zero the second word before
than conditionally clear it later. */ than conditionally clear it later. */
words[1] = 0; words[1] = 0;
/* Extract the absolute value into words. */ /* Extract the absolute value into words. */
mpz_export (words, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, i); mpz_export (words, &count, -1, sizeof(HOST_WIDE_INT), 0, 0, i);
/* We assume that all numbers are in range for its type, and that
we never create a type larger than 2*HWI, which is the largest
that the middle-end can handle. */
gcc_assert (count == 1 || count == 2);
/* We don't assume that all numbers are in range for its type.
However, we never create a type larger than 2*HWI, which is the
largest that the middle-end can handle. So, we only take the
first two elements of words, which is equivalent to wrapping the
value if it's larger than the type range. */
low = words[0]; low = words[0];
high = words[1]; high = words[1];
......
2007-03-22 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR fortran/31262
* gfortran.dg/no_range_check_1.f90: New test.
2007-03-22 Dirk Mueller <dmueller@suse.de> 2007-03-22 Dirk Mueller <dmueller@suse.de>
* g++.old-deja/g++.brendan/warnings2.C: Don't use -pedantic. * g++.old-deja/g++.brendan/warnings2.C: Don't use -pedantic.
! { dg-do run }
! { dg-options "-fno-range-check -O0" }
!
! This testcase arose from PR 31262
integer :: a
integer(kind=8) :: b
a = -3
b = -huge(b) / 7
a = a ** 73
b = 7894_8 * b - 78941_8
if ((-3)**73 /= a) call abort
if (7894_8 * (-huge(b) / 7) - 78941_8 /= b) call abort
a = 1234789786453123
if (a - 1234789786453123 /= a - (-426244989)) call abort
end
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