From: Rafael Garcia-Suarez Date: Fri, 7 Jul 2006 09:50:35 +0000 (+0000) Subject: Fix the implementation of list assignment to state(). X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=9fdc7570b9ab74673d2bcedaa774679d10c80ea0;p=p5sagit%2Fp5-mst-13.2.git Fix the implementation of list assignment to state(). p4raw-id: //depot/perl@28499 --- diff --git a/op.c b/op.c index 4716788..ad110e1 100644 --- a/op.c +++ b/op.c @@ -3800,17 +3800,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) curop->op_type == OP_PADHV || curop->op_type == OP_PADANY) { - if (curop->op_private & OPpPAD_STATE) { - if (left->op_private & OPpLVAL_INTRO) { - o->op_private |= OPpASSIGN_STATE; - /* hijacking PADSTALE for uninitialized state variables */ - SvPADSTALE_on(PAD_SVl(curop->op_targ)); - } - else if (ckWARN(WARN_MISC)) { - Perl_warner(aTHX_ packWARN(WARN_MISC), "State variable %s will be reinitialized", - PAD_COMPNAME_PV(curop->op_targ)); - } - } if (PAD_COMPNAME_GEN(curop->op_targ) == (STRLEN)PL_generation) break; @@ -3849,6 +3838,34 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) if (curop != o) o->op_private |= OPpASSIGN_COMMON; } + + if ( ((left->op_private & OPpLVAL_INTRO) || ckWARN(WARN_MISC)) + && (left->op_type == OP_LIST + || (left->op_type == OP_NULL && left->op_targ == OP_LIST))) + { + OP* lop = ((LISTOP*)left)->op_first; + while (lop) { + if (lop->op_type == OP_PADSV || + lop->op_type == OP_PADAV || + lop->op_type == OP_PADHV || + lop->op_type == OP_PADANY) + { + if (lop->op_private & OPpPAD_STATE) { + if (left->op_private & OPpLVAL_INTRO) { + o->op_private |= OPpASSIGN_STATE; + /* hijacking PADSTALE for uninitialized state variables */ + SvPADSTALE_on(PAD_SVl(lop->op_targ)); + } + else { /* we already checked for WARN_MISC before */ + Perl_warner(aTHX_ packWARN(WARN_MISC), "State variable %s will be reinitialized", + PAD_COMPNAME_PV(lop->op_targ)); + } + } + } + lop = lop->op_sibling; + } + } + if (right && right->op_type == OP_SPLIT) { OP* tmpop = ((LISTOP*)right)->op_first; if (tmpop && (tmpop->op_type == OP_PUSHRE)) { diff --git a/t/lib/warnings/op b/t/lib/warnings/op index 3c10751..8dadc7a 100644 --- a/t/lib/warnings/op +++ b/t/lib/warnings/op @@ -1089,12 +1089,15 @@ state($x) = 1; (state $y) = 2; (state $z, my $t) = (3, 4); (state $foo, state $bar) = (5, 6); +(undef, my $v, state $w) = (7 .. 9); no warnings 'misc'; state($x) = 1; (state $y) = 2; (state $z, my $t) = (3, 4); (state $foo, state $bar) = (5, 6); +(undef, my $v, state $w) = (7 .. 9); EXPECT State variable $z will be reinitialized at - line 6. State variable $foo will be reinitialized at - line 7. State variable $bar will be reinitialized at - line 7. +State variable $w will be reinitialized at - line 8. diff --git a/t/op/state.t b/t/op/state.t index becbb3b..92b4dfc 100644 --- a/t/op/state.t +++ b/t/op/state.t @@ -164,6 +164,4 @@ sub statelist2 { $ls = statelist2(); is($ls, "2/3", 'list assignment to state scalars'); $ls = statelist2(); -{ local our $TODO = 'detection of state vars is misplaced in newASSIGNOP'; is($ls, "3/4", 'list assignment to state scalars'); -}