diff options
author | David Mitchell <davem@iabyn.com> | 2022-04-16 11:48:20 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2022-04-16 18:22:13 +0100 |
commit | f8245cd9653db9b3e3fef57c3913d9deb33972b2 (patch) | |
tree | 754659507371a9a12f8f2a20cbf2a8b814e281a2 /ext/B | |
parent | 55d95e1b172db3fff30c261b7b7ea9e0bca8328a (diff) | |
download | perl-f8245cd9653db9b3e3fef57c3913d9deb33972b2.tar.gz |
for my ($x) ...: fix handling of degenerate 1-var
The new
for my ($x,$y,...) (...) { ... }
syntax has a couple of problems in the degenerate case of a single
variable:
for my ($x) (...) { ... }
First, the loop variable is marked as lexical, but not as a variable
to be introduced. So it behaves roughly as if written like:
{ my $x; for $x (...) { ... } }
I can't think of any user-visible runtime change in behaviour this bug
causes, so I haven't included a test for it.
Second, it was being incorrectly deparsed as
for $x (...) { ... }
(i.e. without the 'my').
This commit fixes both of these issues.
The basic problem is that the parser, in the case of multiple vars,
passes a list subtree of PADSVs as the 'sv' argument of Perl_newFOROP,
but in the case of a single var, passes a single PADSV op instead.
This single PADSV doesn't have the LVINTRO flag set, so is
indistinguishable from plain
my $x; for $x ....
This commit makes the parser set the OPf_PARENS flag on the lone PADSV
to signal to newFOROP() that it's a degenerate 1-var list, and
newFOROP() sets the OPf_PARENS flag on the ENTERITER op to signal to the
deparser that this is "for my (...)" syntax, even if it only has a
single var.
Diffstat (limited to 'ext/B')
-rw-r--r-- | ext/B/t/optree_for.t | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/ext/B/t/optree_for.t b/ext/B/t/optree_for.t index a72324cfaf..415a1492c8 100644 --- a/ext/B/t/optree_for.t +++ b/ext/B/t/optree_for.t @@ -194,7 +194,7 @@ checkOptree ( name => 'for my ($var) (@a)', 2 <0> pushmark sM 3 <#> gv[*a] s 4 <1> rv2av[t3] sKRM/1 -5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KS +5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KPS/LVINTRO 8 <0> iter s 9 <|> and(other->6) K/1 6 <0> stub v @@ -207,7 +207,7 @@ EOT_EOT 2 <0> pushmark sM 3 <$> gv(*a) s 4 <1> rv2av[t2] sKRM/1 -5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KS +5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KPS/LVINTRO 8 <0> iter s 9 <|> and(other->6) K/1 6 <0> stub v @@ -225,7 +225,7 @@ checkOptree ( name => 'for my ($var) (@lexical)', 1 <;> nextstate(main 1466 optree_for.t:100) v 2 <0> pushmark sM 3 <0> padav[@lexical:FAKE::7] sRM -4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KS +4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KPS/LVINTRO 7 <0> iter s 8 <|> and(other->5) K/1 5 <0> stub v @@ -237,7 +237,7 @@ EOT_EOT 1 <;> nextstate(main 424 optree_for.t:111) v:>,<,% 2 <0> pushmark sM 3 <0> padav[@lexical:FAKE::2] sRM -4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KS +4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KPS/LVINTRO 7 <0> iter s 8 <|> and(other->5) K/1 5 <0> stub v @@ -256,7 +256,7 @@ checkOptree ( name => 'for my ($key, $value) (%h)', 2 <0> pushmark sM 3 <#> gv[*h] s 4 <1> rv2hv[t4] lKM -5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] K/LVINTRO +5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] KP/LVINTRO 8 <0> iter s 9 <|> and(other->6) K/1 6 <0> stub v @@ -269,7 +269,7 @@ EOT_EOT 2 <0> pushmark sM 3 <$> gv(*h) s 4 <1> rv2hv[t3] lKM -5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] K/LVINTRO +5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] KP/LVINTRO 8 <0> iter s 9 <|> and(other->6) K/1 6 <0> stub v @@ -288,7 +288,7 @@ checkOptree ( name => 'for my ($foo, $bar, $baz) (@a)', 2 <0> pushmark sM 3 <#> gv[*a] s 4 <1> rv2av[t5] sKRM/1 -5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KS/LVINTRO +5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KPS/LVINTRO 8 <0> iter s 9 <|> and(other->6) K/1 6 <0> stub v @@ -301,7 +301,7 @@ EOT_EOT 2 <0> pushmark sM 3 <$> gv(*a) s 4 <1> rv2av[t4] sKRM/1 -5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KS/LVINTRO +5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KPS/LVINTRO 8 <0> iter s 9 <|> and(other->6) K/1 6 <0> stub v |