summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-03-25 17:07:02 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-03-25 17:07:02 +0000
commitb0988a7bd4c813eb9192cccdce9e18dd347a1771 (patch)
tree54760ab9c61d9af4cc71fca731a499e81bea2ca9
parent46dc00d0d215de143caa9a52f9607347d59fa7cb (diff)
downloadmpfr-b0988a7bd4c813eb9192cccdce9e18dd347a1771.tar.gz
[src/set_{si,ui}_2exp.c] Bug fix in MPFR_LONG_WITHIN_LIMB defined case:
added early underflow/overflow checking to avoid integer overflow or errors due to special exponent values. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@13809 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--src/set_si_2exp.c9
-rw-r--r--src/set_ui_2exp.c9
2 files changed, 18 insertions, 0 deletions
diff --git a/src/set_si_2exp.c b/src/set_si_2exp.c
index f67f84b3e..5e703a47a 100644
--- a/src/set_si_2exp.c
+++ b/src/set_si_2exp.c
@@ -41,6 +41,15 @@ mpfr_set_si_2exp (mpfr_ptr x, long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode)
mp_limb_t ai, *xp;
int inex = 0;
+ /* Early underflow/overflow checking is necessary to avoid
+ integer overflow or errors due to special exponent values. */
+ if (MPFR_UNLIKELY (e < __gmpfr_emin - (mpfr_exp_t)
+ (sizeof (unsigned long) * CHAR_BIT + 1)))
+ return mpfr_underflow (x, rnd_mode == MPFR_RNDN ?
+ MPFR_RNDZ : rnd_mode, i < 0 ? -1 : 1);
+ if (MPFR_UNLIKELY (e >= __gmpfr_emax))
+ return mpfr_overflow (x, rnd_mode, i < 0 ? -1 : 1);
+
ai = SAFE_ABS (unsigned long, i);
MPFR_ASSERTN (SAFE_ABS (unsigned long, i) == ai);
diff --git a/src/set_ui_2exp.c b/src/set_ui_2exp.c
index a0c61068a..fa72613ab 100644
--- a/src/set_ui_2exp.c
+++ b/src/set_ui_2exp.c
@@ -42,6 +42,15 @@ mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode
mp_limb_t *xp;
int inex = 0;
+ /* Early underflow/overflow checking is necessary to avoid
+ integer overflow or errors due to special exponent values. */
+ if (MPFR_UNLIKELY (e < __gmpfr_emin - (mpfr_exp_t)
+ (sizeof (unsigned long) * CHAR_BIT + 1)))
+ return mpfr_underflow (x, rnd_mode == MPFR_RNDN ?
+ MPFR_RNDZ : rnd_mode, i < 0 ? -1 : 1);
+ if (MPFR_UNLIKELY (e >= __gmpfr_emax))
+ return mpfr_overflow (x, rnd_mode, i < 0 ? -1 : 1);
+
MPFR_ASSERTD (i == (mp_limb_t) i);
/* Position of the highest limb */