summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul "LeoNerd" Evans <leonerd@leonerd.org.uk>2021-06-15 00:29:36 +0100
committerPaul Evans <leonerd@leonerd.org.uk>2021-06-17 14:03:46 +0100
commit8f4ba78772d3a6dd19ff509eebf2ef05394e742d (patch)
treec89fc52c7a089cf0855d65446844b8e4589f8cd0
parent19a7e82b4bb19a0d32c179ec2390977ced44f8e5 (diff)
downloadperl-8f4ba78772d3a6dd19ff509eebf2ef05394e742d.tar.gz
scalarseq() should not put an OP_ENTER kid into scalar context (fixes #18855)
-rw-r--r--op.c9
-rw-r--r--t/op/try.t8
2 files changed, 15 insertions, 2 deletions
diff --git a/op.c b/op.c
index bab8de6317..aab97389f2 100644
--- a/op.c
+++ b/op.c
@@ -2622,8 +2622,13 @@ S_voidnonfinal(pTHX_ OP *o)
if (type == OP_LINESEQ || type == OP_SCOPE ||
type == OP_LEAVE || type == OP_LEAVETRY)
{
- OP *kid, *sib;
- for (kid = cLISTOPo->op_first; kid; kid = sib) {
+ OP *kid = cLISTOPo->op_first, *sib;
+ if(type == OP_LEAVE) {
+ /* Don't put the OP_ENTER in void context */
+ assert(kid->op_type == OP_ENTER);
+ kid = OpSIBLING(kid);
+ }
+ for (; kid; kid = sib) {
if ((sib = OpSIBLING(kid))
&& ( OpHAS_SIBLING(sib) || sib->op_type != OP_NULL
|| ( sib->op_targ != OP_NEXTSTATE
diff --git a/t/op/try.t b/t/op/try.t
index 32095662f1..9b0fe2b0b5 100644
--- a/t/op/try.t
+++ b/t/op/try.t
@@ -247,6 +247,14 @@ no warnings 'experimental::try';
catch ($e) { 4, 5, 6 }
};
ok(eq_array(\@list, [4, 5, 6]), 'do { try/catch } in list context');
+
+ # Regression test
+ # https://github.com/Perl/perl5/issues/18855
+ $scalar = do {
+ try { die "Oops" }
+ catch ($e) { my $x = 123; "result" }
+ };
+ is($scalar, "result", 'do { try/catch } with multiple statements');
}
# try{} blocks should be invisible to caller()