diff options
-rw-r--r-- | peep.c | 3 | ||||
-rw-r--r-- | t/op/lex_assign.t | 29 |
2 files changed, 32 insertions, 0 deletions
@@ -3854,6 +3854,8 @@ Perl_rpeep(pTHX_ OP *o) if (!(o->op_private & (OPpASSIGN_BACKWARDS|OPpASSIGN_CV_TO_GV)) && lval && (lval->op_type == OP_PADSV) && !(lval->op_private & OPpDEREF) + /* skip if padrange has already gazumped the padsv */ + && (lval == oldop) ) { /* SASSIGN's bitfield flags, such as op_moresib and @@ -3876,6 +3878,7 @@ Perl_rpeep(pTHX_ OP *o) o->op_targ = lval->op_targ; lval->op_targ = 0; /* Fixup op_next ptrs */ + assert(oldop->op_type == OP_PADSV); /* oldoldop can be arbitrarily deep in the RHS OP tree */ oldoldop->op_next = o; diff --git a/t/op/lex_assign.t b/t/op/lex_assign.t index 6635d888e2..1f97d3988d 100644 --- a/t/op/lex_assign.t +++ b/t/op/lex_assign.t @@ -227,6 +227,35 @@ is($@, '', 'ex-PVBM assert'.$@); cmp_ok($diff, '<', 2, "time delta is small"); } +# GH #20132 and parts of GH ##20114 +# During development of OP_PADSV_STORE, interactions with OP_PADRANGE +# caused BBC failures not picked up by any pre-existing core tests. +# (Problems only arose in list context, the void/scalar tests have been +# included for completeness.) +eval { + my $x = {}; my $y; + keys %{$y = $x}; + 1; +}; +is($@, '', 'keys %{$y = $x}'); + +eval { + my $x = {}; my $y; + my $foo = keys %{$y = $x}; + 1; +}; +is($@, '', 'my $foo = keys %{$y = $x}'); + +eval { + my $x = {}; my $y; + my @foo = keys %{$y = $x}; + 1; +}; +is($@, '', 'my @foo = keys %{$y = $x}'); + +fresh_perl_is('my ($x, $y); (($y = $x))', '', {}, '(($y = $x))'); +fresh_perl_is('my ($x, $y); my $z= (($y = $x))', '', {}, 'my $z= (($y = $x))'); +fresh_perl_is('my ($x, $y); my @z= (($y = $x))', '', {}, 'my @z= (($y = $x))'); done_testing(); |