diff options
author | Father Chrysostomos <sprout@cpan.org> | 2015-01-02 20:15:10 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2015-01-03 16:05:56 -0800 |
commit | 307cbb9fc37bc4e2ceb1d77690249dea0ccbc0ca (patch) | |
tree | b985119437150cc1fc746d7cd643b4c87cd88813 /t/op/lexsub.t | |
parent | fa87ec39c0ab9e6a9009caf5bc528efa6dc8aabc (diff) | |
download | perl-307cbb9fc37bc4e2ceb1d77690249dea0ccbc0ca.tar.gz |
Fix CvOUTSIDE for state subs in predeclared subs
use 5.018;
use experimental 'lexical_subs';
$::x = "global";
sub x;
sub x {
state $x = 42;
state sub x { print eval '$x', "\n" }
\&x;
}
x()->();
__END__
Output:
Segmentation fault: 11
Because this line in pad.c:S_findpadlex:
1141 const PADLIST * const padlist = CvPADLIST(cv);
is trying to read this SV:
SV = UNKNOWN(0x76) (0xaa170e4fd) at 0x10060c928
REFCNT = 1697135711
FLAGS = (PADSTALE,TEMP,GMG,SMG,IOK,pNOK,pPOK,UTF8)
(i.e., gibberish).
During compilation, ‘sub x{’ creates a new CV. When the sub is about
to be installed (when the final ‘}’ is reached), the existing stub
must be reused. So everything is copied from the new CV (PL_compcv)
to the stub. Also, any CvOUTSIDE pointers of nested subs get updated
to point to the erstwhile stub.
State subs were not getting their CvOUTSIDE pointers updated. This
patch implements that.
Diffstat (limited to 't/op/lexsub.t')
-rw-r--r-- | t/op/lexsub.t | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/t/op/lexsub.t b/t/op/lexsub.t index f43285f115..2ba7635e14 100644 --- a/t/op/lexsub.t +++ b/t/op/lexsub.t @@ -7,7 +7,7 @@ BEGIN { *bar::is = *is; *bar::like = *like; } -plan 147; +plan 148; # -------------------- Errors with feature disabled -------------------- # @@ -431,6 +431,18 @@ is runperl(switches => ['-lXMfeature=:all'], like $@, qr/^Undefined subroutine &φου called at /, 'state sub with utf8 name'; } +# This used to crash, but only as a standalone script +is runperl(switches => ['-lXMfeature=:all'], + prog => '$::x = global=>; + sub x; + sub x { + state $x = 42; + state sub x { print eval q|$x| } + x() + } + x()', + stderr => 1), "42\n", + 'closure behaviour of state sub in predeclared package sub'; # -------------------- my -------------------- # |