This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Moving variables to their innermost scope.
[perl5.git] / op.c
diff --git a/op.c b/op.c
index c9e2078..dca52e2 100644 (file)
--- a/op.c
+++ b/op.c
@@ -487,13 +487,13 @@ void
 Perl_opslab_force_free(pTHX_ OPSLAB *slab)
 {
     OPSLAB *slab2;
-    OPSLOT *slot;
 #ifdef DEBUGGING
     size_t savestack_count = 0;
 #endif
     PERL_ARGS_ASSERT_OPSLAB_FORCE_FREE;
     slab2 = slab;
     do {
+        OPSLOT *slot;
        for (slot = slab2->opslab_first;
             slot->opslot_next;
             slot = slot->opslot_next) {
@@ -1865,7 +1865,6 @@ Perl_scalarvoid(pTHX_ OP *arg)
     dVAR;
     OP *kid;
     SV* sv;
-    U8 want;
     SSize_t defer_stack_alloc = 0;
     SSize_t defer_ix = -1;
     OP **defer_stack = NULL;
@@ -1874,6 +1873,7 @@ Perl_scalarvoid(pTHX_ OP *arg)
     PERL_ARGS_ASSERT_SCALARVOID;
 
     do {
+        U8 want;
         SV *useless_sv = NULL;
         const char* useless = NULL;
 
@@ -5843,6 +5843,11 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor)
             rx_flags |= RXf_SPLIT;
         }
 
+        /* Skip compiling if parser found an error for this pattern */
+        if (pm->op_pmflags & PMf_HAS_ERROR) {
+            return o;
+        }
+
        if (!has_code || !eng->op_comp) {
            /* compile-time simple constant pattern */
 
@@ -10558,10 +10563,10 @@ Perl_ck_smartmatch(pTHX_ OP *o)
         op_sibling_splice(o, NULL, 0, first);
        
        /* Implicitly take a reference to a regular expression */
-       if (first->op_type == OP_MATCH) {
+       if (first->op_type == OP_MATCH && !(first->op_flags & OPf_STACKED)) {
             OpTYPE_set(first, OP_QR);
        }
-       if (second->op_type == OP_MATCH) {
+       if (second->op_type == OP_MATCH && !(second->op_flags & OPf_STACKED)) {
             OpTYPE_set(second, OP_QR);
         }
     }
@@ -10890,7 +10895,6 @@ Perl_ck_require(pTHX_ OP *o)
 
     if (o->op_flags & OPf_KIDS) {      /* Shall we supply missing .pm? */
        SVOP * const kid = (SVOP*)cUNOPo->op_first;
-       HEK *hek;
        U32 hash;
        char *s;
        STRLEN len;
@@ -10900,6 +10904,7 @@ Perl_ck_require(pTHX_ OP *o)
          if (kid->op_private & OPpCONST_BARE) {
             dVAR;
            const char *end;
+            HEK *hek;
 
            if (was_readonly) {
                    SvREADONLY_off(sv);
@@ -10942,6 +10947,7 @@ Perl_ck_require(pTHX_ OP *o)
            }
            else {
                 dVAR;
+                HEK *hek;
                if (was_readonly) SvREADONLY_off(sv);
                PERL_HASH(hash, s, len);
                hek = share_hek(s,
@@ -13178,6 +13184,27 @@ S_maybe_multideref(pTHX_ OP *start, OP *orig_o, UV orig_action, U8 hints)
                            && (   (o->op_private & OPpDEREF) == OPpDEREF_AV
                                || (o->op_private & OPpDEREF) == OPpDEREF_HV);
 
+                /* This doesn't make much sense but is legal:
+                 *    @{ local $x[0][0] } = 1
+                 * Since scope exit will undo the autovivification,
+                 * don't bother in the first place. The OP_LEAVE
+                 * assertion is in case there are other cases of both
+                 * OPpLVAL_INTRO and OPpDEREF which don't include a scope
+                 * exit that would undo the local - in which case this
+                 * block of code would need rethinking.
+                 */
+                if (is_deref && (o->op_private & OPpLVAL_INTRO)) {
+#ifdef DEBUGGING
+                    OP *n = o->op_next;
+                    while (n && (  n->op_type == OP_NULL
+                                || n->op_type == OP_LIST))
+                        n = n->op_next;
+                    assert(n && n->op_type == OP_LEAVE);
+#endif
+                    o->op_private &= ~OPpDEREF;
+                    is_deref = FALSE;
+                }
+
                 if (is_deref) {
                     ASSUME(!(o->op_flags &
                                  ~(OPf_WANT|OPf_KIDS|OPf_MOD|OPf_PARENS)));