diff options
-rw-r--r-- | op.h | 2 | ||||
-rw-r--r-- | regcomp.c | 8 | ||||
-rw-r--r-- | t/re/pat_re_eval.t | 37 |
3 files changed, 45 insertions, 2 deletions
@@ -412,7 +412,7 @@ struct pmop { * OP_MATCH and OP_QR */ #define PMf_ONCE (1<<(PMf_BASE_SHIFT+1)) -/* PMf_ONCE has matched successfully. Not used under threading. */ +/* PMf_ONCE, i.e. ?pat?, has matched successfully. Not used under threading. */ #define PMf_USED (1<<(PMf_BASE_SHIFT+3)) /* subst replacement is constant */ @@ -6350,6 +6350,14 @@ reStudy: PerlIO_printf(Perl_debug_log, "\n"); }); #endif + +#ifdef USE_ITHREADS + /* under ithreads the ?pat? PMf_USED flag on the pmop is simulated + * by setting the regexp SV to readonly-only instead. If the + * pattern's been recompiled, the USEDness should remain. */ + if (old_re && SvREADONLY(old_re)) + SvREADONLY_on(rx); +#endif return rx; } diff --git a/t/re/pat_re_eval.t b/t/re/pat_re_eval.t index ddc53f7f03..061e7e5076 100644 --- a/t/re/pat_re_eval.t +++ b/t/re/pat_re_eval.t @@ -23,7 +23,7 @@ BEGIN { } -plan tests => 459; # Update this when adding/deleting tests. +plan tests => 463; # Update this when adding/deleting tests. run_tests() unless caller; @@ -1004,7 +1004,42 @@ sub run_tests { } } + # [perl #115080] + # Ensure that ?pat? matches exactly once, even when the run-time + # pattern changes, and even when the presence of run-time (?{}) affects + # how and when patterns are recompiled + { + my $m; + + $m = ''; + for (qw(a a a)) { + $m .= $_ if m?$_?; + } + is($m, 'a', '?pat? with a,a,a'); + + $m = ''; + for (qw(a b c)) { + $m .= $_ if m?$_?; + } + is($m, 'a', '?pat? with a,b,c'); + + use re 'eval'; + + $m = ''; + for (qw(a a a)) { + my $e = qq[(??{"$_"})]; + $m .= $_ if m?$e?; + } + is($m, 'a', '?pat? with (??{a,a,a})'); + + $m = ''; + for (qw(a b c)) { + my $e = qq[(??{"$_"})]; + $m .= $_ if m?$e?; + } + is($m, 'a', '?pat? with (??{a,b,c})'); + } } # End of sub run_tests |