This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_multideref: tweak an assertion
authorDavid Mitchell <davem@iabyn.com>
Sat, 18 Feb 2017 10:46:53 +0000 (10:46 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sat, 18 Feb 2017 10:46:53 +0000 (10:46 +0000)
My recent commit v5.25.9-89-g43dbb3c added an assertion to the effect that
in

    @{ local $a[0]{b}[1] } = 1;

the 'local' could only appear at the end of a block and so asserted that the
next op should be OP_LEAVE. However, this:

    @{1, local $a[0]{b}[1] } = 1;

inserts an OP_LIST before the OP_LEAVE.

Improve the assert to cope with any number of OP_NULL or OP_LISTs before
the OP_LEAVE.

op.c
t/op/multideref.t

diff --git a/op.c b/op.c
index f16c6b5..66c4a9b 100644 (file)
--- a/op.c
+++ b/op.c
@@ -13193,7 +13193,13 @@ S_maybe_multideref(pTHX_ OP *start, OP *orig_o, UV orig_action, U8 hints)
                  * block of code would need rethinking.
                  */
                 if (is_deref && (o->op_private & OPpLVAL_INTRO)) {
                  * block of code would need rethinking.
                  */
                 if (is_deref && (o->op_private & OPpLVAL_INTRO)) {
-                    assert(o->op_next->op_type == OP_LEAVE);
+#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;
                 }
                     o->op_private &= ~OPpDEREF;
                     is_deref = FALSE;
                 }
index 87c57e8..199e523 100644 (file)
@@ -18,7 +18,7 @@ BEGIN {
 use warnings;
 use strict;
 
 use warnings;
 use strict;
 
-plan 60;
+plan 62;
 
 
 # check that strict refs hint is handled
 
 
 # check that strict refs hint is handled
@@ -216,4 +216,10 @@ sub defer {}
     like $@, qr/Can't use an undefined value as an ARRAY reference/,
                     "RT #130727 error";
     ok !defined $x[0][0],"RT #130727 array not autovivified";
     like $@, qr/Can't use an undefined value as an ARRAY reference/,
                     "RT #130727 error";
     ok !defined $x[0][0],"RT #130727 array not autovivified";
+
+    eval { @{1, local $x[0][0]} = 1; };
+    like $@, qr/Can't use an undefined value as an ARRAY reference/,
+                    "RT #130727 part 2: error";
+    ok !defined $x[0][0],"RT #130727 part 2: array not autovivified";
+
 }
 }