diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-08-05 14:23:42 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-08-05 14:23:42 +0000 |
commit | 47dcac97f8004116930b2d692a93628696baedff (patch) | |
tree | c75a92c189139311327aecf6784d8ccfed383eac /gcc/wide-int.cc | |
parent | 6700f705d1d04e8876fbc0654432c68542563616 (diff) |
gcc/
PR middle-end/66311
* wide-int.cc (wi::from_mpz): Make sure that absolute mpz value
is zero- rather than sign-extended.
gcc/testsuite/
2015-08-05 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR middle-end/66311
* gfortran.dg/pr66311.f90: New file.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@226632 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/wide-int.cc')
-rw-r--r-- | gcc/wide-int.cc | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc index 13ba10c866f..9a93660defc 100644 --- a/gcc/wide-int.cc +++ b/gcc/wide-int.cc @@ -252,13 +252,15 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap) } /* Determine the number of unsigned HOST_WIDE_INTs that are required - for representing the value. The code to calculate count is + for representing the absolute 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 = CHAR_BIT * sizeof (HOST_WIDE_INT); count = (mpz_sizeinbase (x, 2) + numb - 1) / numb; HOST_WIDE_INT *val = res.write_val (); - /* Write directly to the wide_int storage if possible, otherwise leave + /* Read the absolute value. + + 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 @@ -276,7 +278,12 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap) memcpy (val, valres, count * sizeof (HOST_WIDE_INT)); free (valres); } - res.set_len (canonize (val, count, prec)); + /* Zero-extend the absolute value to PREC bits. */ + if (count < BLOCKS_NEEDED (prec) && val[count - 1] < 0) + val[count++] = 0; + else + count = canonize (val, count, prec); + res.set_len (count); if (mpz_sgn (x) < 0) res = -res; |