Skip to content

Commit a52c82b

Browse files
committed
builtin: make inf/nan conditional depending on float support
On some machines (VAX), the double type doesn't support Infinity/NaN values. Handle this case by making builtin::inf/builtin::nan throw a runtime error. Fixes Perl#22882.
1 parent 6c4c496 commit a52c82b

File tree

5 files changed

+62
-13
lines changed

5 files changed

+62
-13
lines changed

builtin.c

+16
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,12 @@ XS(XS_builtin_inf)
9696
dXSARGS;
9797
if(items)
9898
croak_xs_usage(cv, "");
99+
#ifdef DOUBLE_HAS_INF
99100
EXTEND(SP, 1);
100101
XSRETURN_NV(NV_INF);
102+
#else
103+
Perl_croak_nocontext("builtin::inf not implemented");
104+
#endif
101105
}
102106

103107
XS(XS_builtin_nan);
@@ -106,8 +110,12 @@ XS(XS_builtin_nan)
106110
dXSARGS;
107111
if(items)
108112
croak_xs_usage(cv, "");
113+
#ifdef DOUBLE_HAS_NAN
109114
EXTEND(SP, 1);
110115
XSRETURN_NV(NV_NAN);
116+
#else
117+
Perl_croak_nocontext("builtin::nan not implemented");
118+
#endif
111119
}
112120

113121
enum {
@@ -135,8 +143,16 @@ static OP *ck_builtin_const(pTHX_ OP *entersubop, GV *namegv, SV *ckobj)
135143
switch(builtin->ckval) {
136144
case BUILTIN_CONST_FALSE: constval = &PL_sv_no; break;
137145
case BUILTIN_CONST_TRUE: constval = &PL_sv_yes; break;
146+
#ifdef DOUBLE_HAS_INF
138147
case BUILTIN_CONST_INF: constval = newSVnv(NV_INF); break;
148+
#else
149+
case BUILTIN_CONST_INF: return entersubop;
150+
#endif
151+
#ifdef DOUBLE_HAS_NAN
139152
case BUILTIN_CONST_NAN: constval = newSVnv(NV_NAN); break;
153+
#else
154+
case BUILTIN_CONST_NAN: return entersubop;
155+
#endif
140156
default:
141157
DIE(aTHX_ "panic: unrecognised builtin_const value %" IVdf,
142158
builtin->ckval);

lib/builtin.pm

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package builtin 0.017;
1+
package builtin 0.018;
22

33
use v5.40;
44

@@ -167,7 +167,8 @@ Available starting with Perl 5.36.
167167
168168
This function is currently B<experimental>.
169169
170-
Returns the floating-point infinity value.
170+
Returns the floating-point infinity value. If the underlying numeric C type
171+
does not support such a value, it throws a runtime error instead.
171172
172173
Available starting with Perl 5.40.
173174
@@ -177,7 +178,8 @@ Available starting with Perl 5.40.
177178
178179
This function is currently B<experimental>.
179180
180-
Returns the floating-point "Not-a-Number" value.
181+
Returns the floating-point "Not-a-Number" value. If the underlying numeric C
182+
type does not support such a value, it throws a runtime error instead.
181183
182184
Available starting with Perl 5.40.
183185

lib/builtin.t

+23-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ BEGIN {
88

99
use v5.36;
1010
no warnings 'experimental::builtin';
11+
use Config;
1112

1213
package FetchStoreCounter {
1314
sub TIESCALAR($class, @args) { bless \@args, $class }
@@ -55,19 +56,31 @@ package FetchStoreCounter {
5556
{
5657
use builtin qw( inf nan );
5758

58-
ok(inf, 'inf is true');
59-
ok(inf > 1E10, 'inf is bigger than 1E10');
60-
ok(inf == inf, 'inf is equal to inf');
61-
ok(inf == inf + 1, 'inf is equal to inf + 1');
59+
if ($Config{d_double_has_inf}) {
60+
ok(inf, 'inf is true');
61+
ok(inf > 1E10, 'inf is bigger than 1E10');
62+
ok(inf == inf, 'inf is equal to inf');
63+
ok(inf == inf + 1, 'inf is equal to inf + 1');
6264

63-
# Invoke the real XSUB
64-
my $inf = ( \&builtin::inf )->();
65-
ok($inf == $inf + 1, 'inf returned by real xsub');
65+
# Invoke the real XSUB
66+
my $inf = ( \&builtin::inf )->();
67+
ok($inf == $inf + 1, 'inf returned by real xsub');
68+
} else {
69+
is(eval { inf }, undef, 'inf throws');
70+
my $e = $@;
71+
like($e, qr/^builtin::inf not implemented at/, 'inf fails with correct error');
72+
}
6673

67-
ok(nan != nan, 'NaN is not equal to NaN');
74+
if ($Config{d_double_has_nan}) {
75+
ok(nan != nan, 'NaN is not equal to NaN');
6876

69-
my $nan = ( \&builtin::nan )->();
70-
ok($nan != $nan, 'NaN returned by real xsub');
77+
my $nan = ( \&builtin::nan )->();
78+
ok($nan != $nan, 'NaN returned by real xsub');
79+
} else {
80+
is(eval { nan }, undef, 'nan throws');
81+
my $e = $@;
82+
like($e, qr/^builtin::nan not implemented at/, 'nan fails with correct error');
83+
}
7184
}
7285

7386
# weakrefs

pod/perldelta.pod

+8
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ L<XXX> has been upgraded from version A.xx to B.yy.
129129

130130
XXX If there was something important to note about this change, include that here.
131131

132+
=item *
133+
134+
L<builtin> has been upgraded from version 0.017 to 0.018.
135+
136+
On platforms that don't support Inf/NaN values in floating-point numbers (such
137+
as VAX), C<builtin::inf> and C<builtin::nan> now throw a runtime error (rather
138+
than breaking the perl build). [GH #22882]
139+
132140
=back
133141

134142
=head2 Removed Modules and Pragmata

pod/perldiag.pod

+10
Original file line numberDiff line numberDiff line change
@@ -675,6 +675,16 @@ is currently being compiled. Since this method is used to introduce new
675675
lexical subroutines into the scope currently being compiled, this is not
676676
going to have any effect.
677677

678+
=item builtin::inf not implemented
679+
680+
(F) Your machine doesn't support infinity as a numeric value (probably because
681+
it's a VAX).
682+
683+
=item builtin::nan not implemented
684+
685+
(F) Your machine doesn't support NaN ("not a number") as a numeric value
686+
(probably because it's a VAX).
687+
678688
=item Builtin version bundle "%s" is not supported by Perl
679689

680690
(F) You attempted to C<use builtin :ver> for a version number that is either

0 commit comments

Comments
 (0)