summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-11-30 17:46:38 -0800
committerFather Chrysostomos <sprout@cpan.org>2014-11-30 19:10:28 -0800
commitd100ca43dce2c9a6bb636517e5595aa9e1e01e7e (patch)
tree857d861b1c071376886d5c5499dcac13d3880747
parentbf3d06aaf43f2ffb6919a7c464f39a2d65c45b42 (diff)
downloadperl-d100ca43dce2c9a6bb636517e5595aa9e1e01e7e.tar.gz
Fix assertion failure with qr/\Q(?{})/
\Q and \u create ops that need targets, and hence use the pad of the anonymous sub created temporarily when parsing something like qr/\Q(?{})/. If it turns out we don’t have a code block (in this case), that anon sub is thrown away, but there is an assertion that makes sure its pad has not been used, which fails: $ ./perl -e 'qr/\Q(?{})/' Assertion failed: (AvFILLp(PL_comppad) == 0), function Perl_pmruntime, file op.c, line 5395. Abort trap: 6 (That assertion was added by d63c20f27.) If we have had \Q or \l, then the length of the pad may be more than 1, but constant folding should have stolen the values from the pad, so assert that instead.
-rw-r--r--op.c13
-rw-r--r--t/re/rxcode.t6
2 files changed, 16 insertions, 3 deletions
diff --git a/op.c b/op.c
index fdf2a0311a..a3391a27ed 100644
--- a/op.c
+++ b/op.c
@@ -5391,8 +5391,17 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg, I32 floor)
* were wrong (e.g. /[(?{}]/ ). Throw away the PL_compcv
* that isn't required now. Note that we have to be pretty
* confident that nothing used that CV's pad while the
- * regex was parsed */
- assert(AvFILLp(PL_comppad) == 0); /* just @_ */
+ * regex was parsed, except maybe op targets for \Q etc.
+ * If there were any op targets, though, they should have
+ * been stolen by constant folding.
+ */
+#ifdef DEBUGGING
+ PADOFFSET i = 0;
+ assert(PadnamelistMAXNAMED(PL_comppad_name) == 0);
+ while (++i <= AvFILLp(PL_comppad)) {
+ assert(!PL_curpad[i]);
+ }
+#endif
/* But we know that one op is using this CV's slab. */
cv_forget_slab(PL_compcv);
LEAVE_SCOPE(floor);
diff --git a/t/re/rxcode.t b/t/re/rxcode.t
index aa2ea092d8..d043f447d5 100644
--- a/t/re/rxcode.t
+++ b/t/re/rxcode.t
@@ -6,7 +6,7 @@ BEGIN {
set_up_inc('../lib');
}
-plan tests => 41;
+plan tests => 42;
$^R = undef;
like( 'a', qr/^a(?{1})(?:b(?{2}))?/, 'a =~ ab?' );
@@ -98,3 +98,7 @@ cmp_ok( scalar(@var), '==', 0, '..still nothing pushed (package)' );
@a = 1..3;
like eval { qr/@a(?{})/ }, qr/1 2 3\(\?\{\}\)/, 'qr/@a(?{})/';
+
+# Not a code block, but looks a bit like one. (Failed an assertion from
+# 5.17.1 to 5.21.6.)
+ok "(?{" =~ qr/\Q(?{/, 'qr/\Q(?{/';