diff options
author | Joel Brobecker <brobecker@gnat.com> | 2012-07-25 18:27:21 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2012-07-25 18:27:21 +0000 |
commit | 33d7655bb2b3cc12ac5401ae107a0aca33085d6e (patch) | |
tree | a45a8f48f08d796940de8a83d903bde13a7f1f12 /gdb/doublest.c | |
parent | Add support for --enable-lmcheck configure option. (diff) | |
download | binutils-gdb-33d7655bb2b3cc12ac5401ae107a0aca33085d6e.tar.gz binutils-gdb-33d7655bb2b3cc12ac5401ae107a0aca33085d6e.tar.bz2 binutils-gdb-33d7655bb2b3cc12ac5401ae107a0aca33085d6e.zip |
convert_doublest_to_floatformat: handle off-range values.
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.
Diffstat (limited to 'gdb/doublest.c')
-rw-r--r-- | gdb/doublest.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/gdb/doublest.c b/gdb/doublest.c index c8c9e05932c..f683002020f 100644 --- a/gdb/doublest.c +++ b/gdb/doublest.c @@ -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); |