aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/real.c12
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr23941.c9
3 files changed, 27 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 118b6b6..2a56ded 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-09-19 Richard Henderson <rth@redhat.com>
+
+ PR 23941
+ * real.c (exact_real_truncate): Return false if the format cannot
+ represent the number as a normal.
+
2005-09-19 Dorit Nuzman <dorit@il.ibm.com>
* tree-ssa-operands.c (swap_tree_operands): Export.
diff --git a/gcc/real.c b/gcc/real.c
index 2d26185..9b165ec 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -2399,7 +2399,19 @@ real_value_truncate (enum machine_mode mode, REAL_VALUE_TYPE a)
bool
exact_real_truncate (enum machine_mode mode, const REAL_VALUE_TYPE *a)
{
+ const struct real_format *fmt;
REAL_VALUE_TYPE t;
+ int emin2m1;
+
+ fmt = REAL_MODE_FORMAT (mode);
+ gcc_assert (fmt);
+
+ /* Don't allow conversion to denormals. */
+ emin2m1 = (fmt->emin - 1) * fmt->log2_b;
+ if (REAL_EXP (a) <= emin2m1)
+ return false;
+
+ /* After conversion to the new mode, the value must be identical. */
real_convert (&t, mode, a);
return real_identical (&t, a);
}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr23941.c b/gcc/testsuite/gcc.c-torture/execute/pr23941.c
new file mode 100644
index 0000000..4dfd645
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr23941.c
@@ -0,0 +1,9 @@
+extern void abort (void);
+double d = __FLT_MIN__ / 2.0;
+int main()
+{
+ double x = __FLT_MIN__ / 2.0;
+ if (x != d)
+ abort ();
+ return 0;
+}