sprintf2.t: mark TODO bad denorm values under g++

Some t/op/sprintf2.t tests were failing under g++. This is due the perl
toker interpreting very small literal hex floating pointers as 0 rather
than as a subnormal value.

For example:

    perl -le'print "bad" if 0x1.fffffffffffffp-1022 == 0.0'

This breaks some of the sprintf2.t tests, so mark them TODO them if the
literal value evaluates to zero.

Note that this is a bug in the toker/g++/glibc rather than sprintf.

The issue is due to the use of pow() in scan_num():

under gcc and plain g++, pow(2.0, -1074) returns the smallest denorm
number; however, under 'g++ -ansi', it returns 0.0.
This commit is contained in:
David Mitchell 2018-05-01 15:28:49 +01:00
parent e8d0f503dd
commit 38c84d6ad1

View File

@ -808,7 +808,17 @@ SKIP: {
for my $t (@subnormals) {
# Note that "0x1p+2" is not considered numeric,
# since neither is "0x12", hence the eval.
my $s = sprintf($t->[1], eval $t->[0]);
my $f = eval $t->[0];
# XXX under g++ -ansi, pow(2.0, -1074) returns 0 rather
# than the smallest denorm number. Which means that very small
# string literals on a perl compiled under g++ may be seen as 0.
# This is either a bug in the g++ math library or scan_num() in
# toke.c; but in either case, its not a bug in sprintf(), so
# skip the test.
local $::TODO = "denorm literals treated as zero"
if $f == 0.0 && $t->[2] ne '0x0p+0';
my $s = sprintf($t->[1], $f);
is($s, $t->[2], "subnormal @$t got $s");
}