From: Vincent Pit Date: Thu, 14 May 2015 15:38:01 +0000 (+0200) Subject: Make sure gv ops seen by multideref are cleaned from the global table X-Git-Tag: v0.15~3 X-Git-Url: http://git.vpit.fr/?a=commitdiff_plain;h=32f02f03f98df22086b067e5e81be90c1f83d030;p=perl%2Fmodules%2Fautovivification.git Make sure gv ops seen by multideref are cleaned from the global table Since they are created in the peephole optimizer, multideref ops have to rely on getting the lexical scope hints from their first kid. It might have happened that the kid of one such op was a gv op compiled in the scope of the pragma, and was then reused outside of the scope of the pragma again as the first kid of another multideref op. In that case, the multideref op was wrongly replaced. This is solved by always clearing gv ops entries in ck_rv2xv() from the global op map. This solves random failures of test 12 from t/40-scope.t. --- diff --git a/autovivification.xs b/autovivification.xs index e038c73..eb1cbbc 100644 --- a/autovivification.xs +++ b/autovivification.xs @@ -1258,14 +1258,19 @@ static OP *a_ck_deref(pTHX_ OP *o) { } o = old_ck(aTHX_ o); - if (hint & A_HINT_DO) { #if A_HAS_MULTIDEREF - if (old_ck == a_old_ck_rv2sv && o->op_flags & OPf_KIDS) { - OP *kid = cUNOPo->op_first; - if (kid && kid->op_type == OP_GV) + if (old_ck == a_old_ck_rv2sv && o->op_flags & OPf_KIDS) { + OP *kid = cUNOPo->op_first; + if (kid && kid->op_type == OP_GV) { + if (hint & A_HINT_DO) a_map_store(kid, kid->op_ppaddr, NULL, hint); + else + a_map_delete(kid); } + } #endif + + if (hint & A_HINT_DO) { a_map_store_root(o, o->op_ppaddr, hint); o->op_ppaddr = a_pp_deref; } else