aboutsummaryrefslogtreecommitdiff
path: root/stdlib/gen-tst-strtod-round.c
diff options
context:
space:
mode:
authorJoseph Myers <josmyers@redhat.com>2024-08-27 12:38:01 +0000
committerJoseph Myers <josmyers@redhat.com>2024-08-27 12:38:01 +0000
commitd73ed2601b7c3c93c3529149a3d7f7b6177900a8 (patch)
tree29d0d031d20b75b48efcccbeb689df350822e5d9 /stdlib/gen-tst-strtod-round.c
parent3de73f974fab55430177c811c9c9ba3f251d5747 (diff)
downloadglibc-d73ed2601b7c3c93c3529149a3d7f7b6177900a8.tar.xz
glibc-d73ed2601b7c3c93c3529149a3d7f7b6177900a8.zip
More thoroughly test underflow / errno in tst-strtod-round
Add tests of underflow in tst-strtod-round, and thus also test for errno being unchanged when there is neither overflow nor underflow. The errno setting before the function call to test for being unchanged is adjusted to set errno to 12345 instead of 0, so that any bugs where strtod sets errno to 0 would be detected. This doesn't add any new test inputs for tst-strtod-round, and in particular doesn't cover the edge cases of underflow the way tst-strtod-underflow does (none of the existing test inputs for tst-strtod-round actually exercise cases that have underflow with before-rounding tininess detection but not with after-rounding tininess detection), but at least it provides some coverage (as per the recent discussions) that ordinary non-overflowing non-underflowing inputs to these functions do not set errno. Tested for x86_64.
Diffstat (limited to 'stdlib/gen-tst-strtod-round.c')
-rw-r--r--stdlib/gen-tst-strtod-round.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/stdlib/gen-tst-strtod-round.c b/stdlib/gen-tst-strtod-round.c
index e48bf4d6ea..7ce735f81d 100644
--- a/stdlib/gen-tst-strtod-round.c
+++ b/stdlib/gen-tst-strtod-round.c
@@ -46,6 +46,7 @@ static int
string_to_fp (mpfr_t f, const char *s, mpfr_rnd_t rnd)
{
mpfr_clear_overflow ();
+ mpfr_clear_underflow ();
#ifdef WORKAROUND
mpfr_t f2;
mpfr_init2 (f2, 100000);
@@ -53,12 +54,16 @@ string_to_fp (mpfr_t f, const char *s, mpfr_rnd_t rnd)
int r = mpfr_set (f, f2, rnd);
r |= mpfr_subnormalize (f, r, rnd);
mpfr_clear (f2);
- return r0 | r;
+ r |= r0;
#else
int r = mpfr_strtofr (f, s, NULL, 0, rnd);
r |= mpfr_subnormalize (f, r, rnd);
- return r;
#endif
+ if (r == 0)
+ /* The MPFR underflow flag is set for exact subnormal results,
+ which is not wanted here. */
+ mpfr_clear_underflow ();
+ return r;
}
void
@@ -70,6 +75,21 @@ print_fp (FILE *fout, mpfr_t f, const char *suffix)
mpfr_fprintf (fout, "\t%Ra%s", f, suffix);
}
+static const char *
+suffix_to_print (bool overflow, bool underflow, bool underflow_before_rounding,
+ bool with_comma)
+{
+ if (overflow)
+ return with_comma ? ", true, false,\n" : ", true, false";
+ if (underflow)
+ return with_comma ? ", false, true,\n" : ", false, true";
+ if (underflow_before_rounding)
+ return (with_comma
+ ? ", false, !TININESS_AFTER_ROUNDING,\n"
+ : ", false, !TININESS_AFTER_ROUNDING");
+ return with_comma ? ", false, false,\n" : ", false, false";
+}
+
static void
round_str (FILE *fout, const char *s, int prec, int emin, int emax,
bool ibm_ld)
@@ -80,8 +100,11 @@ round_str (FILE *fout, const char *s, int prec, int emin, int emax,
mpfr_set_emin (emin);
mpfr_set_emax (emax);
mpfr_init (f);
+ string_to_fp (f, s, MPFR_RNDZ);
+ bool underflow_before_rounding = mpfr_underflow_p () != 0;
int r = string_to_fp (f, s, MPFR_RNDD);
bool overflow = mpfr_overflow_p () != 0;
+ bool underflow = mpfr_underflow_p () != 0;
if (ibm_ld)
{
assert (prec == 106 && emin == -1073 && emax == 1024);
@@ -97,19 +120,27 @@ round_str (FILE *fout, const char *s, int prec, int emin, int emax,
}
}
mpfr_fprintf (fout, "\t%s,\n", r ? "false" : "true");
- print_fp (fout, f, overflow ? ", true,\n" : ", false,\n");
+ print_fp (fout, f,
+ suffix_to_print (overflow, underflow, underflow_before_rounding,
+ true));
string_to_fp (f, s, MPFR_RNDN);
overflow = (mpfr_overflow_p () != 0
|| (ibm_ld && mpfr_cmpabs (f, max_value) > 0));
- print_fp (fout, f, overflow ? ", true,\n" : ", false,\n");
+ print_fp (fout, f,
+ suffix_to_print (overflow, underflow, underflow_before_rounding,
+ true));
string_to_fp (f, s, MPFR_RNDZ);
overflow = (mpfr_overflow_p () != 0
|| (ibm_ld && mpfr_cmpabs (f, max_value) > 0));
- print_fp (fout, f, overflow ? ", true,\n" : ", false,\n");
+ print_fp (fout, f,
+ suffix_to_print (overflow, underflow, underflow_before_rounding,
+ true));
string_to_fp (f, s, MPFR_RNDU);
overflow = (mpfr_overflow_p () != 0
|| (ibm_ld && mpfr_cmpabs (f, max_value) > 0));
- print_fp (fout, f, overflow ? ", true" : ", false");
+ print_fp (fout, f,
+ suffix_to_print (overflow, underflow, underflow_before_rounding,
+ false));
mpfr_clear (f);
if (ibm_ld)
mpfr_clear (max_value);