Like fake scalars, state variables shouldn't get new pad entries
Rafael Garcia-Suarez [Mon, 12 Mar 2007 14:33:01 +0000 (14:33 +0000)]
at each recursion, in order to be truly stateful. (bug #41789)

p4raw-id: //depot/perl@30548

pad.c
t/op/state.t

diff --git a/pad.c b/pad.c
index f565ce2..8560d9a 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -1619,7 +1619,10 @@ Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
        for ( ;ix > 0; ix--) {
            if (names_fill >= ix && names[ix] != &PL_sv_undef) {
                const char sigil = SvPVX_const(names[ix])[0];
-               if ((SvFLAGS(names[ix]) & SVf_FAKE) || sigil == '&') {
+               if ((SvFLAGS(names[ix]) & SVf_FAKE)
+                       || (SvFLAGS(names[ix]) & SVpad_STATE)
+                       || sigil == '&')
+               {
                    /* outer lexical or anon code */
                    av_store(newpad, ix, SvREFCNT_inc(oldpad[ix]));
                }
index 92b4dfc..9f618b0 100644 (file)
@@ -10,7 +10,7 @@ BEGIN {
 use strict;
 use feature "state";
 
-plan tests => 34;
+plan tests => 37;
 
 ok( ! defined state $uninit, q(state vars are undef by default) );
 
@@ -165,3 +165,13 @@ $ls = statelist2();
 is($ls, "2/3", 'list assignment to state scalars');
 $ls = statelist2();
 is($ls, "3/4", 'list assignment to state scalars');
+
+# Recursion
+
+sub noseworth {
+    my $level = shift;
+    state $recursed_state = 123;
+    is($recursed_state, 123, "state kept through recursion ($level)");
+    noseworth($level - 1) if $level;
+}
+noseworth(2);