summaryrefslogtreecommitdiff
path: root/ext/B
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2022-04-16 11:48:20 +0100
committerDavid Mitchell <davem@iabyn.com>2022-04-16 18:22:13 +0100
commitf8245cd9653db9b3e3fef57c3913d9deb33972b2 (patch)
tree754659507371a9a12f8f2a20cbf2a8b814e281a2 /ext/B
parent55d95e1b172db3fff30c261b7b7ea9e0bca8328a (diff)
downloadperl-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.t16
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