Change 33009 by [EMAIL PROTECTED] on 2008/01/19 20:41:03 [perl #49522] state variable not available Svf_PADSTALE means something different for state vars. Make sure we always handle it correctly
Affected files ... ... //depot/perl/pad.c#119 edit ... //depot/perl/t/op/state.t#20 edit Differences ... ==== //depot/perl/pad.c#119 (text) ==== Index: perl/pad.c --- perl/pad.c#118~32906~ 2008-01-08 17:50:38.000000000 -0800 +++ perl/pad.c 2008-01-19 12:41:03.000000000 -0800 @@ -102,6 +102,8 @@ { my $x = 1; sub f { eval '$x'} } f(); +For state vars, SVf_PADSTALE is overloaded to mean 'not yet initialised' + =cut */ @@ -768,6 +770,7 @@ else { int newwarn = warn; if (!CvCOMPILED(cv) && (*out_flags & PAD_FAKELEX_MULTI) + && !SvPAD_STATE(name_svp[offset]) && warn && ckWARN(WARN_CLOSURE)) { newwarn = 0; Perl_warner(aTHX_ packWARN(WARN_CLOSURE), @@ -796,7 +799,9 @@ "Pad findlex cv=0x%"UVxf" found lex=0x%"UVxf"\n", PTR2UV(cv), PTR2UV(*out_capture))); - if (SvPADSTALE(*out_capture)) { + if (SvPADSTALE(*out_capture) + && !SvPAD_STATE(name_svp[offset])) + { if (ckWARN(WARN_CLOSURE)) Perl_warner(aTHX_ packWARN(WARN_CLOSURE), "Variable \"%s\" is not available", name); @@ -853,7 +858,7 @@ ? SvSTASH(*out_name_sv) : NULL, SvOURSTASH(*out_name_sv), 1, /* fake */ - 0 /* not a state variable */ + SvPAD_STATE(*out_name_sv) ? 1 : 0 /* state variable ? */ ); new_namesv = AvARRAY(PL_comppad_name)[new_offset]; @@ -1496,8 +1501,8 @@ assert(sv); /* formats may have an inactive parent, while my $x if $false can leave an active var marked as - stale */ - if (SvPADSTALE(sv)) { + stale. And state vars are always available */ + if (SvPADSTALE(sv) && !SvPAD_STATE(namesv)) { if (ckWARN(WARN_CLOSURE)) Perl_warner(aTHX_ packWARN(WARN_CLOSURE), "Variable \"%s\" is not available", SvPVX_const(namesv)); ==== //depot/perl/t/op/state.t#20 (text) ==== Index: perl/t/op/state.t --- perl/t/op/state.t#19~31840~ 2007-09-10 07:04:40.000000000 -0700 +++ perl/t/op/state.t 2008-01-19 12:41:03.000000000 -0800 @@ -10,7 +10,7 @@ use strict; use feature ":5.10"; -plan tests => 123; +plan tests => 130; ok( ! defined state $uninit, q(state vars are undef by default) ); @@ -354,6 +354,50 @@ eval $forbidden; like $@, qr/Initialization of state variables in list context currently forbidden/, "Currently forbidden: $forbidden"; } + +# [perl #49522] state variable not available + +{ + my @warnings; + local $SIG{__WARN__} = sub { push @warnings, $_[0] }; + + eval q{ + use warnings; + + sub f_49522 { + state $s = 88; + sub g_49522 { $s } + sub { $s }; + } + + sub h_49522 { + state $t = 99; + sub i_49522 { + sub { $t }; + } + } + }; + is $@, '', "eval f_49522"; + # shouldn't be any 'not available' or 'not stay shared' warnings + ok [EMAIL PROTECTED], "suppress warnings part 1 [EMAIL PROTECTED]"; + + @warnings = (); + my $f = f_49522(); + is $f->(), 88, "state var closure 1"; + is g_49522(), 88, "state var closure 2"; + ok [EMAIL PROTECTED], "suppress warnings part 2 [EMAIL PROTECTED]"; + + + @warnings = (); + $f = i_49522(); + h_49522(); # initialise $t + is $f->(), 99, "state var closure 3"; + ok [EMAIL PROTECTED], "suppress warnings part 3 [EMAIL PROTECTED]"; + + +} + + __DATA__ state ($a) = 1; (state $a) = 1; End of Patch.