convert_doublest_to_floatformat: handle off-range values.
authorJoel Brobecker <brobecker@gnat.com>
Wed, 25 Jul 2012 18:27:21 +0000 (18:27 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Wed, 25 Jul 2012 18:27:21 +0000 (18:27 +0000)
On x86_64-linux targetting AVR, we see the following issues:

    (gdb) print 1.6e+308
    $1 = 0.89002949
    (gdb) print 1.6e-308
    $3 = 2.87630892

What happens is that GDB is trying to convert the value it read
(as a host "long double") into a target "double" value. The routine
performing the conversion does not realize that 1.6e+308 is just
too large to fit in a double. Similarly, it does not notice that
1.6e-308 is too small to be represented.

This patch enhances convert_doublest_to_floatformat to both handle
floats that are too small and too large.

gdb/ChangeLog:

        * doublest.c (convert_doublest_to_floatformat): If the exponent
        is too small, treat the value as zero.  If the exponent is too
        large, treat the value as infinity.

gdb/ChangeLog
gdb/doublest.c

index b5aa871600025261738b2b37d41656ce44f1a681..2c1520b5ddc5df48beae3b0cbbea402e43b143d7 100644 (file)
@@ -1,3 +1,9 @@
+2012-07-25  Joel Brobecker  <brobecker@adacore.com>
+
+       * doublest.c (convert_doublest_to_floatformat): If the exponent
+       is too small, treat the value as zero.  If the exponent is too
+       large, treat the value as infinity.
+
 2012-07-25  Joel Brobecker  <brobecker@adacore.com>
 
        * configure.ac: Add --enable-lmcheck configure option.
index c8c9e05932c29de15524a5af8c704014d2a8f091..f683002020ffbd308476de54b61ad71e8803560d 100644 (file)
@@ -472,6 +472,28 @@ convert_doublest_to_floatformat (CONST struct floatformat *fmt,
   mant = frexp (dfrom, &exponent);
 #endif
 
+  if (exponent + fmt->exp_bias <= 0)
+    {
+      /* The value is too small to be expressed in the destination
+        type (not enough bits in the exponent.  Treat as 0.  */
+      put_field (uto, order, fmt->totalsize, fmt->exp_start,
+                fmt->exp_len, 0);
+      put_field (uto, order, fmt->totalsize, fmt->man_start,
+                fmt->man_len, 0);
+      goto finalize_byteorder;
+    }
+
+  if (exponent + fmt->exp_bias >= (1 << fmt->exp_len) - 1)
+    {
+      /* The value is too large to fit into the destination.
+        Treat as infinity.  */
+      put_field (uto, order, fmt->totalsize, fmt->exp_start,
+                fmt->exp_len, fmt->exp_nan);
+      put_field (uto, order, fmt->totalsize, fmt->man_start,
+                fmt->man_len, 0);
+      goto finalize_byteorder;
+    }
+
   put_field (uto, order, fmt->totalsize, fmt->exp_start, fmt->exp_len,
             exponent + fmt->exp_bias - 1);