aboutsummaryrefslogtreecommitdiff
path: root/gcc/wide-int.cc
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-05 14:23:42 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-05 14:23:42 +0000
commit47dcac97f8004116930b2d692a93628696baedff (patch)
treec75a92c189139311327aecf6784d8ccfed383eac /gcc/wide-int.cc
parent6700f705d1d04e8876fbc0654432c68542563616 (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.cc13
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;