Commit ad000635d3 for perl
commit ad000635d3a1cfde6a725553f3acb9cee7ee3455
Author: Paul Evans <leonerd@leonerd.org.uk>
Date: Thu Oct 29 17:08:27 2026 +0000
B::Concise: correct handling of refafliasing in pp_enteriter
diff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm
index eddea66ae4..ba3a4f5d1f 100644
--- a/ext/B/B/Concise.pm
+++ b/ext/B/B/Concise.pm
@@ -1,4 +1,4 @@
-package B::Concise 1.012;
+package B::Concise 1.013;
# Copyright (C) 2000-2003 Stephen McCamant. All rights reserved.
# This program is free software; you can redistribute and/or modify it
# under the same terms as Perl itself.
@@ -847,14 +847,25 @@ sub concise_op {
# for my ($q, $r, $s) () {} syntax hijacks the targ of the iter op,
# (which is the ->next of the enteriter) hence the special cases above
# and just below:
- my $count = $h{name} eq 'padrange'
- ? ($op->private & $B::Op_private::defines{'OPpPADRANGE_COUNTMASK'})
- : $h{name} eq 'enteriter'
- ? $op->next->targ + 1
- : 1;
+ my $count = 1; my $refmask = 0;
+ if ($h{name} eq 'padrange') {
+ $count = $op->private & $B::Op_private::defines{'OPpPADRANGE_COUNTMASK'};
+ }
+ elsif ($h{name} eq 'enteriter') {
+ my $iterop = $op->next;
+ if ($iterop->private & $B::Op_private::defines{'OPpITER_REFALIAS'}) {
+ $count = ($iterop->targ & 0xFF) + 1;
+ $refmask = ($iterop->targ >> 8);
+ }
+ else {
+ $count = $iterop->targ + 1;
+ }
+ };
my (@targarg, @targarglife);
for my $i (0..$count-1) {
my ($targarg, $targarglife) = padname($h{targ} + $i);
+ $targarg = "\\$targarg", $targarglife = "\\$targarglife"
+ if $i < 24 and $refmask & (1<<$i);
push @targarg, $targarg;
push @targarglife, $targarglife;
}
diff --git a/ext/B/t/optree_for.t b/ext/B/t/optree_for.t
index f5d5a4d243..997c04f7ce 100644
--- a/ext/B/t/optree_for.t
+++ b/ext/B/t/optree_for.t
@@ -9,7 +9,7 @@ BEGIN {
}
}
use OptreeCheck;
-plan tests => 19;
+plan tests => 21;
pass("FOR LOOPS");
@@ -292,3 +292,37 @@ EOT_EOT
9 <2> leaveloop K/2
a <1> leavesub[1 ref] K/REFC,1
EONT_EONT
+
+checkOptree ( name => 'for my ($x, \@y) (1..4)',
+ code => sub {
+ use feature qw( declared_refs refaliasing );
+ no warnings qw( experimental::declared_refs experimental::refaliasing );
+ for my ($x, \@y) (1..4) {}
+ },
+ bcopts => '-exec',
+ strip_open_hints => 1,
+ expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
+1 <;> nextstate(main 1652 optree_for.t:300) v:%,{,fea=15
+2 <0> pushmark s
+3 <$> const[IV 1] s
+4 <$> const[IV 4] s
+5 <{> enteriter(next->6 last->9 redo->6)[$x:1653,1656; \@y:1653,1656] KPS/LVINTRO
+7 <0> iter s/REFALIAS
+8 <|> and(other->6) K/1
+6 <0> unstack s
+ goto 7
+9 <2> leaveloop K/2
+a <1> leavesub[1 ref] K/REFC,1
+EOT_EOT
+1 <;> nextstate(main 1652 optree_for.t:300) v:%,{,fea=15
+2 <0> pushmark s
+3 <$> const(IV 1) s
+4 <$> const(IV 4) s
+5 <{> enteriter(next->6 last->9 redo->6)[$x:1653,1656; \@y:1653,1656] KPS/LVINTRO
+7 <0> iter s/REFALIAS
+8 <|> and(other->6) K/1
+6 <0> unstack s
+ goto 7
+9 <2> leaveloop K/2
+a <1> leavesub[1 ref] K/REFC,1
+EONT_EONT