This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
5.22.3-RC4 and 5.24.1-RC4 today
[perl5.git] / op.c
diff --git a/op.c b/op.c
index d6d7a84..697faa7 100644 (file)
--- a/op.c
+++ b/op.c
@@ -4763,7 +4763,7 @@ Perl_op_convert_list(pTHX_ I32 type, I32 flags, OP *o)
     if (type != OP_SPLIT)
         /* At this point o is a LISTOP, but OP_SPLIT is a PMOP; let
          * ck_split() create a real PMOP and leave the op's type as listop
-         * for for now. Otherwise op_free() etc will crash.
+         * for now. Otherwise op_free() etc will crash.
          */
         OpTYPE_set(o, type);
 
@@ -5594,7 +5594,7 @@ S_set_haseval(pTHX)
  * constant), or convert expr into a runtime regcomp op sequence (if it's
  * not)
  *
- * Flags currently has 2 bits or meaning:
+ * Flags currently has 2 bits of meaning:
  * 1: isreg indicates that the pattern is part of a regex construct, eg
  * $x =~ /pattern/ or split /pattern/, as opposed to $x =~ $pattern or
  * split "pattern", which aren't. In the former case, expr will be a list
@@ -6586,14 +6586,13 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
             {
                 /* @pkg or @lex or local @pkg' or 'my @lex' */
                 OP *tmpop;
-                PMOP * const pm = (PMOP*)right;
                 if (gvop) {
 #ifdef USE_ITHREADS
-                    pm->op_pmreplrootu.op_pmtargetoff
+                    ((PMOP*)right)->op_pmreplrootu.op_pmtargetoff
                         = cPADOPx(gvop)->op_padix;
                     cPADOPx(gvop)->op_padix = 0;       /* steal it */
 #else
-                    pm->op_pmreplrootu.op_pmtargetgv
+                    ((PMOP*)right)->op_pmreplrootu.op_pmtargetgv
                         = MUTABLE_GV(cSVOPx(gvop)->op_sv);
                     cSVOPx(gvop)->op_sv = NULL;        /* steal it */
 #endif
@@ -6601,7 +6600,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                         left->op_private & OPpOUR_INTRO;
                 }
                 else {
-                    pm->op_pmreplrootu.op_pmtargetoff = left->op_targ;
+                    ((PMOP*)right)->op_pmreplrootu.op_pmtargetoff = left->op_targ;
                     left->op_targ = 0; /* steal it */
                     right->op_private |= OPpSPLIT_LEX;
                 }
@@ -11151,7 +11150,7 @@ Perl_ck_split(pTHX_ OP *o)
     kid = cLISTOPo->op_first;
 
     if (kid->op_type != OP_MATCH || kid->op_flags & OPf_STACKED) {
-        /* remove match expression, and replace with new optree  with
+        /* remove match expression, and replace with new optree with
          * a match op at its head */
         op_sibling_splice(o, NULL, 1, NULL);
         /* pmruntime will handle split " " behavior with flag==2 */
@@ -11170,10 +11169,10 @@ Perl_ck_split(pTHX_ OP *o)
      * into its place, then convert the match op into a split op. i.e.
      *
      *  SPLIT                    MATCH                 SPLIT(ex-MATCH)
-     *    |                        |                     |               
-     *  MATCH - A - B - C   =>     R - A - B - C   =>    R - A - B - C 
-     *    |                        |                     |               
-     *    R                        X - Y                 X - Y           
+     *    |                        |                     |
+     *  MATCH - A - B - C   =>     R - A - B - C   =>    R - A - B - C
+     *    |                        |                     |
+     *    R                        X - Y                 X - Y
      *    |
      *    X - Y
      *
@@ -12520,6 +12519,7 @@ S_aassign_scan(pTHX_ OP* o, bool rhs, bool top, int *scalars_p)
     case OP_PADAV:
     case OP_PADHV:
         (*scalars_p) += 2;
+        /* if !top, could be e.g. @a[0,1] */
         if (top && (o->op_flags & OPf_REF))
             return (o->op_private & OPpLVAL_INTRO)
                 ? AAS_MY_AGG : AAS_LEX_AGG;
@@ -12540,6 +12540,7 @@ S_aassign_scan(pTHX_ OP* o, bool rhs, bool top, int *scalars_p)
         if (cUNOPx(o)->op_first->op_type != OP_GV)
             return AAS_DANGEROUS; /* @{expr}, %{expr} */
         /* @pkg, %pkg */
+        /* if !top, could be e.g. @a[0,1] */
         if (top && (o->op_flags & OPf_REF))
             return AAS_PKG_AGG;
         return AAS_DANGEROUS;
@@ -12553,17 +12554,32 @@ S_aassign_scan(pTHX_ OP* o, bool rhs, bool top, int *scalars_p)
         return AAS_PKG_SCALAR; /* $pkg */
 
     case OP_SPLIT:
-        if (1) { /* XXX this condition is wrong - fix later
-        if (cLISTOPo->op_first->op_type == OP_PUSHRE) {
-        */
-            /* "@foo = split... " optimises away the aassign and stores its
-             * destination array in the OP_PUSHRE that precedes it.
-             * A flattened array is always dangerous.
+        if (o->op_private & OPpSPLIT_ASSIGN) {
+            /* the assign in @a = split() has been optimised away
+             * and the @a attached directly to the split op
+             * Treat the array as appearing on the RHS, i.e.
+             *    ... = (@a = split)
+             * is treated like
+             *    ... = @a;
              */
+
+            if (o->op_flags & OPf_STACKED)
+                /* @{expr} = split() - the array expression is tacked
+                 * on as an extra child to split - process kid */
+                return S_aassign_scan(aTHX_ cLISTOPo->op_last, rhs,
+                                        top, scalars_p);
+
+            /* ... else array is directly attached to split op */
             (*scalars_p) += 2;
-            return AAS_DANGEROUS;
+            if (PL_op->op_private & OPpSPLIT_LEX)
+                return (o->op_private & OPpLVAL_INTRO)
+                    ? AAS_MY_AGG : AAS_LEX_AGG;
+            else
+                return AAS_PKG_AGG;
         }
-        break;
+        (*scalars_p)++;
+        /* other args of split can't be returned */
+        return AAS_SAFE_SCALAR;
 
     case OP_UNDEF:
         /* undef counts as a scalar on the RHS: