This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #115066] Fix wrongly nested ‘use’ deparsing
authorFather Chrysostomos <sprout@cpan.org>
Sat, 15 Nov 2014 17:56:50 +0000 (09:56 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 15 Nov 2014 18:58:52 +0000 (10:58 -0800)
B::Deparse was incorrectly putting ‘use’ statements and BEGIN blocks
inside other ‘use’ statements containing do-blocks, even if they were
originally outside.

Subroutines (except for cloned closures, which we don’t have to worry
about here) have an OUTSIDE pointer, pointing to the outer sub con-
taining the declaration of the sub in question.  So we can check that
to make sure we are putting the sub declaration in the right place.

Not only does this fix the reported case, but it also will allow
sequence numbers in inner subs to be reused by statements in outer
subs, which I may need in a future commit.

lib/B/Deparse.pm
lib/B/Deparse.t

index 3a943e4..1e42ef1 100644 (file)
@@ -1645,10 +1645,18 @@ sub seq_subs {
 #push @text, "# ($seq)\n";
 
     return "" if !defined $seq;
+    my @pending;
     while (scalar(@{$self->{'subs_todo'}})
           and $seq > $self->{'subs_todo'}[0][0]) {
+       my $cv = $self->{'subs_todo'}[0][1];
+       my $outside = $cv && $cv->OUTSIDE;
+       if ($cv and ${$cv->OUTSIDE || \0} != ${$self->{'curcv'}}) {
+           push @pending, shift @{$self->{'subs_todo'}};
+           next;
+       }
        push @text, $self->next_todo;
     }
+    unshift @{$self->{'subs_todo'}}, @pending;
     return @text;
 }
 
index bdc54f4..d73d858 100644 (file)
@@ -367,12 +367,11 @@ EOCODJ
 }
 
 # [perl #115066]
-$::TODO = ' ';
 my $prog = 'use constant FOO => do { 1 }; no overloading; die';
 $a = readpipe qq`$^X $path "-MO=-qq,Deparse" -e "$prog" 2>&1`;
 is($a, <<'EOCODK', '[perl #115066] use statements accidentally nested');
 use constant ('FOO', do {
-    1;
+    1
 });
 no overloading;
 die;