This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Document variants of ‘Can’t modify’ individually
[perl5.git] / op.c
diff --git a/op.c b/op.c
index c6d8d25..f26f0d3 100644 (file)
--- a/op.c
+++ b/op.c
@@ -678,9 +678,7 @@ optree.
 void
 Perl_op_free(pTHX_ OP *o)
 {
-#ifdef USE_ITHREADS
     dVAR;
-#endif
     OPCODE type;
 
     /* Though ops may be freed twice, freeing the op after its slab is a
@@ -2357,7 +2355,6 @@ S_lvref(pTHX_ OP *o, I32 type)
        o->op_flags |= OPf_STACKED;
        if (o->op_flags & OPf_PARENS) {
            if (o->op_private & OPpLVAL_INTRO) {
-                /* diag_listed_as: Can't modify %s in %s */
                 yyerror(Perl_form(aTHX_ "Can't modify reference to "
                      "localized parenthesized array in list assignment"));
                return;
@@ -2391,7 +2388,6 @@ S_lvref(pTHX_ OP *o, I32 type)
     case OP_RV2HV:
        if (o->op_flags & OPf_PARENS) {
          parenhash:
-           /* diag_listed_as: Can't modify %s in %s */
            yyerror(Perl_form(aTHX_ "Can't modify reference to "
                                 "parenthesized hash in list assignment"));
                return;
@@ -2448,7 +2444,7 @@ S_lvref(pTHX_ OP *o, I32 type)
        /* FALLTHROUGH */
     default:
       badref:
-       /* diag_listed_as: Can't modify %s in %s */
+       /* diag_listed_as: Can't modify reference to %s in %s assignment */
        yyerror(Perl_form(aTHX_ "Can't modify reference to %s in %s",
                     o->op_type == OP_NULL && o->op_flags & OPf_SPECIAL
                      ? "do block"
@@ -2774,12 +2770,12 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
            const U8 ec = PL_parser ? PL_parser->error_count : 0;
            S_lvref(aTHX_ kid, type);
            if (!PL_parser || PL_parser->error_count == ec) {
-               if (!FEATURE_LVREF_IS_ENABLED)
+               if (!FEATURE_REFALIASING_IS_ENABLED)
                    Perl_croak(aTHX_
-                            "Experimental lvalue references not enabled");
+                      "Experimental aliasing via reference not enabled");
                Perl_ck_warner_d(aTHX_
-                                packWARN(WARN_EXPERIMENTAL__LVALUE_REFS),
-                             "Lvalue references are experimental");
+                                packWARN(WARN_EXPERIMENTAL__REFALIASING),
+                               "Aliasing via reference is experimental");
            }
        }
        if (o->op_type == OP_REFGEN)
@@ -6135,9 +6131,9 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
        if (right && right->op_type == OP_SPLIT
         && !(right->op_flags & OPf_STACKED)) {
            OP* tmpop = ((LISTOP*)right)->op_first;
-           if (tmpop && (tmpop->op_type == OP_PUSHRE)) {
-               PMOP * const pm = (PMOP*)tmpop;
-               if (
+           PMOP * const pm = (PMOP*)tmpop;
+           assert (tmpop && (tmpop->op_type == OP_PUSHRE));
+           if (
 #ifdef USE_ITHREADS
                    !pm->op_pmreplrootu.op_pmtargetoff
 #else
@@ -6216,7 +6212,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                          }
                        }
                    }
-               }
            }
        }
        return o;
@@ -10171,18 +10166,18 @@ Perl_ck_refassign(pTHX_ OP *o)
        break;
     default:
       bad:
-       /* diag_listed_as: Can't modify %s in %s */
+       /* diag_listed_as: Can't modify reference to %s in %s assignment */
        yyerror(Perl_form(aTHX_ "Can't modify reference to %s in scalar "
                                "assignment",
                                 OP_DESC(varop)));
        return o;
     }
-    if (!FEATURE_LVREF_IS_ENABLED)
+    if (!FEATURE_REFALIASING_IS_ENABLED)
        Perl_croak(aTHX_
-                 "Experimental lvalue references not enabled");
+                 "Experimental aliasing via reference not enabled");
     Perl_ck_warner_d(aTHX_
-                    packWARN(WARN_EXPERIMENTAL__LVALUE_REFS),
-                   "Lvalue references are experimental");
+                    packWARN(WARN_EXPERIMENTAL__REFALIASING),
+                   "Aliasing via reference is experimental");
     o->op_private |= varop->op_private & (OPpLVAL_INTRO|OPpPAD_STATE);
     if (stacked) o->op_flags |= OPf_STACKED;
     else {
@@ -11658,19 +11653,11 @@ S_inplace_aassign(pTHX_ OP *o) {
 STATIC void
 S_null_listop_in_list_context(pTHX_ OP *o)
 {
-    OP *kid;
-
     PERL_ARGS_ASSERT_NULL_LISTOP_IN_LIST_CONTEXT;
 
     /* This is an OP_LIST in list (or void) context. That means we
      * can ditch the OP_LIST and the OP_PUSHMARK within. */
 
-    kid = cLISTOPo->op_first;
-    /* Find the end of the chain of OPs executed within the OP_LIST. */
-    while (kid->op_next != o)
-        kid = kid->op_next;
-
-    kid->op_next = o->op_next; /* patch list out of exec chain */
     op_null(cUNOPo->op_first); /* NULL the pushmark */
     op_null(o); /* NULL the list */
 }
@@ -12083,7 +12070,7 @@ Perl_rpeep(pTHX_ OP *o)
                 followop = p->op_next;
             }
 
-            if (count < 1)
+            if (count < 1 || (count == 1 && !defav))
                 break;
 
             /* pp_padrange in specifically compile-time void context
@@ -12094,17 +12081,16 @@ Perl_rpeep(pTHX_ OP *o)
              * padrange.
              * In particular in void context, we can only optimise to
              * a padrange if see see the complete sequence
-             *     pushmark, pad*v, ...., list, nextstate
-             * which has the net effect of of leaving the stack empty
-             * (for now we leave the nextstate in the execution chain, for
-             * its other side-effects).
+             *     pushmark, pad*v, ...., list
+             * which has the net effect of of leaving the markstack as it
+             * was.  Not pushing on to the stack (whereas padsv does touch
+             * the stack) makes no difference in void context.
              */
             assert(followop);
             if (gimme == OPf_WANT_VOID) {
-                if (OP_TYPE_IS_OR_WAS(followop, OP_LIST)
+                if (followop->op_type == OP_LIST
                         && gimme == (followop->op_flags & OPf_WANT)
-                        && (   followop->op_next->op_type == OP_NEXTSTATE
-                            || followop->op_next->op_type == OP_DBSTATE))
+                   )
                 {
                     followop = followop->op_next; /* skip OP_LIST */