diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2015-11-06 18:54:16 -0500 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2015-11-15 12:02:07 +0000 |
commit | fff4a2c9645dffe498ae699ff5d35c1a74670f94 (patch) | |
tree | 85aa204fdb93e3ddd7b7a4cd8d564d3e9d65c51c | |
parent | 9a8b9949c11e771441d869f5fee53bfc5c006253 (diff) | |
download | perl-fff4a2c9645dffe498ae699ff5d35c1a74670f94.tar.gz |
perl #126582 hexfp overflow drops hi-order bits
(cherry picked from commit 0c8adad77d308bd7d386922521a57b894a2bf959)
-rw-r--r-- | t/op/hexfp.t | 22 | ||||
-rw-r--r-- | toke.c | 16 |
2 files changed, 28 insertions, 10 deletions
diff --git a/t/op/hexfp.t b/t/op/hexfp.t index 30aaf1160c..e83050e348 100644 --- a/t/op/hexfp.t +++ b/t/op/hexfp.t @@ -10,7 +10,7 @@ use strict; use Config; -plan(tests => 79); +plan(tests => 85); # Test hexfloat literals. @@ -169,9 +169,27 @@ SKIP: eval '0x1.fffffffffffffp+1024'; like(get_warn(), qr/^Hexadecimal float: exponent overflow/); + + undef $a; + eval '$a = 0x111.0000000000000p+0'; # 12 zeros. + like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); + is($a, 273); + + # The 13 zeros would be enough to push the hi-order digits + # off the high-end. + + undef $a; + eval '$a = 0x111.0000000000000p+0'; # 13 zeros. + like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); + is($a, 273); + + undef $a; + eval '$a = 0x111.00000000000000p+0'; # 14 zeros. + like(get_warn(), qr/^Hexadecimal float: mantissa overflow/); + is($a, 273); } else { print "# skipping warning tests\n"; - skip "nv_preserves_uv_bits is $Config{nv_preserves_uv_bits} not 53", 8; + skip "nv_preserves_uv_bits is $Config{nv_preserves_uv_bits} not 53", 14; } } @@ -10232,21 +10232,21 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp) #ifdef HEXFP_NV NV mult = 1 / 16.0; #endif - h++; - while (isXDIGIT(*h) || *h == '_') { + for (h++; (isXDIGIT(*h) || *h == '_'); h++) { if (isXDIGIT(*h)) { U8 b = XDIGIT_VALUE(*h); total_bits += shift; + if (total_bits < NV_MANT_DIG) { #ifdef HEXFP_UQUAD - hexfp_uquad <<= shift; - hexfp_uquad |= b; - hexfp_frac_bits += shift; + hexfp_uquad <<= shift; + hexfp_uquad |= b; + hexfp_frac_bits += shift; #else /* HEXFP_NV */ - hexfp_nv += b * mult; - mult /= 16.0; + hexfp_nv += b * mult; + mult /= 16.0; #endif + } } - h++; } } |