[perl #94390] Optimised numeric sort should warn for nan
authorFather Chrysostomos <sprout@cpan.org>
Thu, 13 Oct 2011 05:53:31 +0000 (22:53 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 13 Oct 2011 06:28:30 +0000 (23:28 -0700)
In this case:

    sort { $a <=> $b } ...

the sort block is optimised away and implemented in C.

That C implementation did not take into account that $a or $b might be
nan, and therefore, without optimisation, would return undef, result-
ing in a warning.

The optimisation is supposed to be just that, and not change
behaviour.

pp_sort.c
t/lib/warnings/9uninit

index fafa00a..0ee42dc 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1874,6 +1874,14 @@ S_sv_ncmp(pTHX_ SV *const a, SV *const b)
 
     PERL_ARGS_ASSERT_SV_NCMP;
 
+#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
+    if (Perl_isnan(right) || Perl_isnan(left)) {
+#else
+    if (nv1 != nv1 || nv2 != nv2) {
+#endif
+       if (ckWARN(WARN_UNINITIALIZED)) report_uninit(NULL);
+       return 0;
+    }
     return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0;
 }
 
index a30352a..b79fc01 100644 (file)
@@ -655,6 +655,22 @@ Use of uninitialized value $g1 in sort at - line 9.
 Use of uninitialized value in sort at - line 10.
 Use of uninitialized value in sort at - line 11.
 ########
+my $nan = sin 9**9**9;
+if ($nan == $nan) {
+    print <<EOM ;
+SKIPPED
+# No nan support
+EOM
+    exit ;
+}
+use warnings 'uninitialized';
+# The optimised {$a<=>$b} case should behave the same way as unoptimised.
+@sort = sort { ($a)[0] <=> $b } 1, $nan;
+@sort = sort {  $a     <=> $b } 1, $nan;
+EXPECT
+Use of uninitialized value in sort at - line 11.
+Use of uninitialized value in sort at - line 12.
+########
 use warnings 'uninitialized';
 my ($m1, $m2, $v);
 our ($g1);