This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[MERGE] rpeep() consistent oldoldop -> oldop -> o
authorDavid Mitchell <davem@iabyn.com>
Wed, 9 Dec 2015 14:34:46 +0000 (14:34 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 9 Dec 2015 14:34:46 +0000 (14:34 +0000)
op.c
t/op/my.t

diff --git a/op.c b/op.c
index d8dfbd3..0de303c 100644 (file)
--- a/op.c
+++ b/op.c
@@ -13127,6 +13127,11 @@ Perl_rpeep(pTHX_ OP *o)
        }
 
       redo:
+
+        /* oldoldop -> oldop -> o should be a chain of 3 adjacent ops */
+        assert(!oldoldop || oldoldop->op_next == oldop);
+        assert(!oldop    || oldop->op_next    == o);
+
        /* By default, this op has now been optimised. A couple of cases below
           clear this again.  */
        o->op_opt = 1;
@@ -13448,9 +13453,10 @@ Perl_rpeep(pTHX_ OP *o)
                    op_null(o);
                    if (oldop)
                        oldop->op_next = nextop;
+                    o = nextop;
                    /* Skip (old)oldop assignment since the current oldop's
                       op_next already points to the next op.  */
-                   continue;
+                   goto redo;
                }
            }
            break;
@@ -13855,7 +13861,8 @@ Perl_rpeep(pTHX_ OP *o)
                    oldoldop = NULL;
                    goto redo;
                }
-               o = oldop;
+               o = oldop->op_next;
+                goto redo;
            }
            else if (o->op_next->op_type == OP_RV2SV) {
                if (!(o->op_next->op_private & OPpDEREF)) {
@@ -14152,6 +14159,11 @@ Perl_rpeep(pTHX_ OP *o)
            op_null(o);
            enter->op_private |= OPpITER_REVERSED;
            iter->op_private |= OPpITER_REVERSED;
+
+            oldoldop = NULL;
+            oldop    = ourlast;
+            o        = oldop->op_next;
+            goto redo;
            
            break;
        }
index 2dca46f..e76fc5e 100644 (file)
--- a/t/op/my.t
+++ b/t/op/my.t
@@ -149,5 +149,10 @@ is( $@, '', 'no errors while checking autovivification and persistence of hash r
 eval "my ()";
 is( $@, '', "eval of my() passes");
 
+# RT #126844
+# This triggered a compile-time assert failure in rpeep()
+eval 'my($a,$b),$x,my($c,$d)';
+pass("RT #126844");
+
 #Variable number of tests due to the way the while/for loops are tested now
 done_testing();