+
+# this happened while the padrange op was being added. Sort blocks
+# are executed in void context, and the padrange op was skipping pushing
+# the item in void cx. The net result was that the return value was
+# whatever was on the stack last.
+
+{
+ my @a = sort {
+ my $r = $a <=> $b;
+ if ($r) {
+ undef; # this got returned by mistake
+ return $r
+ }
+ return 0;
+ } 5,1,3,6,0;
+ is "@a", "0 1 3 5 6", "padrange and void context";
+}
+
+# Fatal warnings an sort sub returning a non-number
+# We need two evals, because the panic used to happen on scope exit.
+eval { eval { use warnings FATAL => 'all'; () = sort { undef } 1,2 } };
+is $@, "",
+ 'no panic/crash with fatal warnings when sort sub returns undef';
+eval { eval { use warnings FATAL => 'all'; () = sort { "no thin" } 1,2 } };
+is $@, "",
+ 'no panic/crash with fatal warnings when sort sub returns string';
+sub notdef($$) { undef }
+eval { eval { use warnings FATAL => 'all'; () = sort notdef 1,2 } };
+is $@, "",
+ 'no panic/crash with fatal warnings when sort sub($$) returns undef';
+sub yarn($$) { "no thinking aloud" }
+eval { eval { use warnings FATAL => 'all'; () = sort yarn 1,2 } };
+is $@, "",
+ 'no panic/crash with fatal warnings when sort sub($$) returns string';
+
+$#a = -1;
+() = [sort { $a = 10; $b = 10; 0 } $#a, $#a];
+is $#a, 10, 'sort block modifying $a and $b';
+
+() = sort {
+ is \$a, \$a, '[perl #78194] op return values passed to sort'; 0
+} "${\''}", "${\''}";
+
+package deletions {
+ @_=sort { delete $deletions::{a}; delete $deletions::{b}; 3 } 1..3;
+}
+pass "no crash when sort block deletes *a and *b";
+
+# make sure return args are always evaluated in scalar context
+
+{
+ package Ret;
+ no warnings 'void';
+ sub f0 { }
+ sub f1 { $b <=> $a, $a <=> $b }
+ sub f2 { return ($b <=> $a, $a <=> $b) }
+ sub f3 { for ($b <=> $a) { return ($b <=> $a, $a <=> $b) } }
+
+ {
+ no warnings 'uninitialized';
+ ::is (join('-', sort { () } 3,1,2,4), '3-1-2-4', "Ret: null blk");
+ }
+ ::is (join('-', sort { $b <=> $a, $a <=> $b } 3,1,2,4), '1-2-3-4', "Ret: blk");
+ ::is (join('-', sort { for($b <=> $a) { return ($b <=> $a, $a <=> $b) } }
+ 3,1,2,4), '1-2-3-4', "Ret: blk ret");
+ {
+ no warnings 'uninitialized';
+ ::is (join('-', sort f0 3,1,2,4), '3-1-2-4', "Ret: f0");
+ }
+ ::is (join('-', sort f1 3,1,2,4), '1-2-3-4', "Ret: f1");
+ ::is (join('-', sort f2 3,1,2,4), '1-2-3-4', "Ret: f2");
+ ::is (join('-', sort f3 3,1,2,4), '1-2-3-4', "Ret: f3");
+}
+
+{
+ @a = sort{ *a=0; 1} 0..1;
+ pass "No crash when GP deleted out from under us [perl 124097]";
+
+ no warnings 'redefine';
+ # some alternative non-solutions localized modifications to *a and *b
+ sub a { 0 };
+ @a = sort { *a = sub { 1 }; $a <=> $b } 0 .. 1;
+ ok(a(), "*a wasn't localized inadvertantly");
+}
+
+SKIP:
+{
+ eval { require Config; 1 }
+ or skip "Cannot load Config", 1;
+ $Config::Config{ivsize} == 8
+ or skip "this test can only fail with 64-bit integers", 1;
+ # sort's built-in numeric comparison wasn't careful enough in a world
+ # of integers with more significant digits than NVs
+ my @in = ( "0", "20000000000000001", "20000000000000000" );
+ my @out = sort { $a <=> $b } @in;
+ is($out[1], "20000000000000000", "check sort order");
+}
+
+# [perl #92264] refcounting of GvSV slot of *a and *b
+{
+ my $act;
+ package ReportDestruction {
+ sub new { bless({ p => $_[1] }, $_[0]) }
+ sub DESTROY { $act .= $_[0]->{p}; }
+ }
+ $act = "";
+ my $filla = \(ReportDestruction->new("[filla]"));
+ () = sort { my $r = $a cmp $b; $act .= "0"; *a = \$$filla; $act .= "1"; $r }
+ ReportDestruction->new("[sorta]"), "foo";
+ $act .= "2";
+ $filla = undef;
+ is $act, "01[sorta]2[filla]";
+ $act = "";
+ my $fillb = \(ReportDestruction->new("[fillb]"));
+ () = sort { my $r = $a cmp $b; $act .= "0"; *b = \$$fillb; $act .= "1"; $r }
+ "foo", ReportDestruction->new("[sortb]");
+ $act .= "2";
+ $fillb = undef;
+ is $act, "01[sortb]2[fillb]";
+}