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.