summaryrefslogtreecommitdiff
path: root/dev-lang/perl/files/5.42.0/0001-newFOROP-fix-crash-when-optimizing-2-var-for-over-bu.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dev-lang/perl/files/5.42.0/0001-newFOROP-fix-crash-when-optimizing-2-var-for-over-bu.patch')
-rw-r--r--dev-lang/perl/files/5.42.0/0001-newFOROP-fix-crash-when-optimizing-2-var-for-over-bu.patch83
1 files changed, 83 insertions, 0 deletions
diff --git a/dev-lang/perl/files/5.42.0/0001-newFOROP-fix-crash-when-optimizing-2-var-for-over-bu.patch b/dev-lang/perl/files/5.42.0/0001-newFOROP-fix-crash-when-optimizing-2-var-for-over-bu.patch
new file mode 100644
index 000000000000..873a6e498728
--- /dev/null
+++ b/dev-lang/perl/files/5.42.0/0001-newFOROP-fix-crash-when-optimizing-2-var-for-over-bu.patch
@@ -0,0 +1,83 @@
+From 7dbc795b44eb54d41e1c6b30d8796525d65d52b5 Mon Sep 17 00:00:00 2001
+Message-ID: <7dbc795b44eb54d41e1c6b30d8796525d65d52b5.1763833678.git.sam@gentoo.org>
+From: Lukas Mai <lukasmai.403@gmail.com>
+Date: Fri, 11 Jul 2025 09:07:00 +0200
+Subject: [PATCH 1/4] newFOROP: fix crash when optimizing 2-var for over
+ builtin::indexed
+
+OP_ENTERSUB isn't necessarily a LISTOP, apparently, so we can't just
+grab its op_last. Instead, copy/paste logic from elsewhere in op.c to
+find the cvop.
+
+Also, avoid crashing on "fake" pad entries that represent lexical subs
+from outer scopes by climbing up the scope chain until we reach a real
+pad entry.
+
+Fixes #23405.
+
+(cherry picked from commit 96673a4bb36a973a9a4c5cd0e5727a799789a32c)
+Signed-off-by: Sam James <sam@gentoo.org>
+---
+ op.c | 14 +++++++++++---
+ t/op/for-many.t | 13 +++++++++++++
+ 2 files changed, 24 insertions(+), 3 deletions(-)
+
+diff --git a/op.c b/op.c
+index f616532c49..3c316ea8b4 100644
+--- a/op.c
++++ b/op.c
+@@ -9665,7 +9665,7 @@ S_op_is_cv_xsub(pTHX_ OP *o, XSUBADDR_t xsub)
+ }
+
+ case OP_PADCV:
+- cv = (CV *)PAD_SVl(o->op_targ);
++ cv = find_lexical_cv(o->op_targ);
+ assert(cv && SvTYPE(cv) == SVt_PVCV);
+ break;
+
+@@ -9683,10 +9683,18 @@ S_op_is_cv_xsub(pTHX_ OP *o, XSUBADDR_t xsub)
+ static bool
+ S_op_is_call_to_cv_xsub(pTHX_ OP *o, XSUBADDR_t xsub)
+ {
+- if(o->op_type != OP_ENTERSUB)
++ if (o->op_type != OP_ENTERSUB)
+ return false;
+
+- OP *cvop = cLISTOPx(cUNOPo->op_first)->op_last;
++ /* entersub may be a UNOP, not a LISTOP, so we can't just use op_last */
++ OP *aop = cUNOPo->op_first;
++ if (!OpHAS_SIBLING(aop)) {
++ aop = cUNOPx(aop)->op_first;
++ }
++ aop = OpSIBLING(aop);
++ OP *cvop;
++ for (cvop = aop; OpHAS_SIBLING(cvop); cvop = OpSIBLING(cvop)) ;
++
+ return op_is_cv_xsub(cvop, xsub);
+ }
+
+diff --git a/t/op/for-many.t b/t/op/for-many.t
+index 2f6790aee7..035d1da07e 100644
+--- a/t/op/for-many.t
++++ b/t/op/for-many.t
+@@ -498,4 +498,17 @@ is($continue, 'xx', 'continue reached twice');
+ is("@have", "Pointy end Up Flamey end Down", 'for my ($one, $two)');
+ }
+
++# GH #23405 - segfaults when compiling 2-var for loops
++{
++ my $dummy = sub {};
++ for my ($x, $y) (main->$dummy) {}
++ pass '2-var for does not crash on method calls';
++
++ my sub dummy {}
++ sub {
++ for my ($x, $y) (dummy) {}
++ }->();
++ pass '2-var for does not crash on lexical sub calls';
++}
++
+ done_testing();
+--
+2.52.0
+