This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Don't use a C++ keyword as a variable name ("new").
[perl5.git] / pp_sort.c
index a239c01..12e77f9 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -9,8 +9,10 @@
  */
 
 /*
- *   ...they shuffled back towards the rear of the line. 'No, not at the
- *   rear!'  the slave-driver shouted. 'Three files up. And stay there...
+ *   ...they shuffled back towards the rear of the line.  'No, not at the
+ *   rear!' the slave-driver shouted.  'Three files up. And stay there...
+ *
+ *     [p.931 of _The Lord of the Rings_, VI/ii: "The Land of Shadow"]
  */
 
 /* This file contains pp ("push/pop") functions that
@@ -204,7 +206,7 @@ dynprep(pTHX_ gptr *list1, gptr *list2, size_t nmemb, const SVCOMPARE_t cmp)
            if (r >= t) p = r = t;      /* too short to care about */
            else {
                while (((cmp(aTHX_ *(p-1), *p) > 0) == sense) &&
-                      ((p -= 2) > q));
+                      ((p -= 2) > q)) {}
                if (p <= q) {
                    /* b through r is a (long) run.
                    ** Extend it as far as possible.
@@ -1289,7 +1291,7 @@ S_qsortsvu(pTHX_ SV ** array, size_t num_elts, SVCOMPARE_t compare)
  * by the original comparison routine on the elements pointed to.
  * Because we don't move the elements of list1 around through
  * this phase, we can break ties on elements that compare equal
- * using their address in the list1 array, ensuring stabilty.
+ * using their address in the list1 array, ensuring stability.
  * This leaves us with something looking like
  *
  *  indir                  list1
@@ -1516,7 +1518,7 @@ PP(pp_sort)
        else {
            cv = sv_2cv(*++MARK, &stash, &gv, 0);
            if (cv && SvPOK(cv)) {
-               const char * const proto = SvPV_nolen_const((SV*)cv);
+               const char * const proto = SvPV_nolen_const(MUTABLE_SV(cv));
                if (proto && strEQ(proto, "$$")) {
                    hasargs = TRUE;
                }
@@ -1566,7 +1568,7 @@ PP(pp_sort)
        }
        else {
            if (SvREADONLY(av))
-               Perl_croak(aTHX_ PL_no_modify);
+               Perl_croak(aTHX_ "%s", PL_no_modify);
            else
                SvREADONLY_on(av);
            p1 = p2 = AvARRAY(av);
@@ -1650,6 +1652,11 @@ PP(pp_sort)
            if (!(flags & OPf_SPECIAL)) {
                cx->cx_type = CXt_SUB;
                cx->blk_gimme = G_SCALAR;
+               /* If our comparison routine is already active (CvDEPTH is
+                * is not 0),  then PUSHSUB does not increase the refcount,
+                * so we have to do it ourselves, because the LEAVESUB fur-
+                * ther down lowers it. */
+               if (CvDEPTH(cv)) SvREFCNT_inc_simple_void_NN(cv);
                PUSHSUB(cx);
                if (!is_xsub) {
                    AV* const padlist = CvPADLIST(cv);
@@ -1755,8 +1762,6 @@ S_sortcv(pTHX_ SV *const a, SV *const b)
     CALLRUNOPS(aTHX);
     if (PL_stack_sp != PL_stack_base + 1)
        Perl_croak(aTHX_ "Sort subroutine didn't return single value");
-    if (!SvNIOKp(*PL_stack_sp))
-       Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value");
     result = SvIV(*PL_stack_sp);
     while (PL_scopestack_ix > oldscopeix) {
        LEAVE;
@@ -1797,8 +1802,6 @@ S_sortcv_stacked(pTHX_ SV *const a, SV *const b)
     CALLRUNOPS(aTHX);
     if (PL_stack_sp != PL_stack_base + 1)
        Perl_croak(aTHX_ "Sort subroutine didn't return single value");
-    if (!SvNIOKp(*PL_stack_sp))
-       Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value");
     result = SvIV(*PL_stack_sp);
     while (PL_scopestack_ix > oldscopeix) {
        LEAVE;
@@ -1827,8 +1830,6 @@ S_sortcv_xsub(pTHX_ SV *const a, SV *const b)
     (void)(*CvXSUB(cv))(aTHX_ cv);
     if (PL_stack_sp != PL_stack_base + 1)
        Perl_croak(aTHX_ "Sort subroutine didn't return single value");
-    if (!SvNIOKp(*PL_stack_sp))
-       Perl_croak(aTHX_ "Sort subroutine didn't return a numeric value");
     result = SvIV(*PL_stack_sp);
     while (PL_scopestack_ix > oldscopeix) {
        LEAVE;