summaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-const.c
diff options
context:
space:
mode:
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-22 22:51:50 +0000
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-22 22:51:50 +0000
commitf2c255d4fa65514614d673a9e440dbe2b92b60b7 (patch)
tree0a5617457fdf2cbc258625c013283ae7a6b8e6b8 /gcc/fortran/trans-const.c
parent63c68695947927f83f1182fb22cb6a272780e1d3 (diff)
downloadgcc-f2c255d4fa65514614d673a9e440dbe2b92b60b7.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123136 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/trans-const.c')
-rw-r--r--gcc/fortran/trans-const.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/gcc/fortran/trans-const.c b/gcc/fortran/trans-const.c
index c1c96619715..5e27134b006 100644
--- a/gcc/fortran/trans-const.c
+++ b/gcc/fortran/trans-const.c
@@ -165,23 +165,33 @@ gfc_conv_mpz_to_tree (mpz_t i, int kind)
}
else
{
- unsigned HOST_WIDE_INT words[2];
- size_t count;
+ unsigned HOST_WIDE_INT *words;
+ 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),
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
than conditionally clear it later. */
words[1] = 0;
-
+
/* Extract the absolute value into words. */
- 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);
+ mpz_export (words, &count, -1, sizeof(HOST_WIDE_INT), 0, 0, i);
+ /* 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];
high = words[1];