This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix deparsing of "" =~ <any OPf_SPECIAL op>
authorFather Chrysostomos <sprout@cpan.org>
Thu, 8 Dec 2011 06:13:50 +0000 (22:13 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 8 Dec 2011 14:18:09 +0000 (06:18 -0800)
This is a regression in 5.14.

$ ./perl -Ilib -MO=Deparse -e '"" =~ do{}'
'' =~ ($_ =~ do {
    ()
});
-e syntax OK

Commit a539498ab05 fixed the deparsing of "foo" =~ (1?/foo/:/bar/),
in which /foo/ is implicitly bound to $_.  Due to constant folding,
the whole condition expression is reduced to "foo" =~ /foo/, but with
/foo/ still bound to $_.  /foo/ is marked OPf_SPECIAL, which allows
us to distinguish the cases.  The fix, which added "$_ =~" explic-
itly, did not check that the op was a match op, so any op on the rhs
with the OPf_SPECIAL flag set could trigger the same special case.

dist/B-Deparse/Deparse.pm
dist/B-Deparse/t/deparse.t

index ab46e7a..c3ac5fa 100644 (file)
@@ -4382,7 +4382,11 @@ sub matchop {
        carp("found ".$kid->name." where regcomp expected");
     } else {
        ($re, $quote) = $self->regcomp($kid, 21, $extended);
-       $rhs_bound_to_defsv = 1 if $kid->first->first->flags & OPf_SPECIAL;
+       my $matchop = $kid->first->first;
+       if ($matchop->name =~ /^(?:match|transr?|subst)\z/
+          && $matchop->flags & OPf_SPECIAL) {
+           $rhs_bound_to_defsv = 1;
+       }
     }
     my $flags = "";
     $flags .= "c" if $op->pmflags & PMf_CONTINUE;
index 2361088..056c9cf 100644 (file)
@@ -725,12 +725,17 @@ pop @_;
 #[perl #20444]
 "foo" =~ (1 ? /foo/ : /bar/);
 "foo" =~ (1 ? y/foo// : /bar/);
+"foo" =~ (1 ? y/foo//r : /bar/);
 "foo" =~ (1 ? s/foo// : /bar/);
 >>>>
 'foo' =~ ($_ =~ /foo/);
 'foo' =~ ($_ =~ tr/fo//);
+'foo' =~ ($_ =~ tr/fo//r);
 'foo' =~ ($_ =~ s/foo//);
 ####
+# The fix for [perl #20444] broke this.
+'foo' =~ do { () };
+####
 # Test @threadsv_names under 5005threads
 foreach $' (1, 2) {
     sleep $';