summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 4f5fd9a038..212c226a92 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2112,7 +2112,7 @@ PP(pp_enteriter)
itervar = &PAD_SVl(PL_op->op_targ);
#endif
}
- else { /* symbol table variable */
+ else if (LIKELY(isGV(TOPs))) { /* symbol table variable */
GV * const gv = MUTABLE_GV(POPs);
SV** svp = &GvSV(gv);
save_pushptrptr(gv, SvREFCNT_inc(*svp), SAVEt_GVSV);
@@ -2120,6 +2120,14 @@ PP(pp_enteriter)
itervar = (void *)gv;
save_aliased_sv(gv);
}
+ else {
+ SV * const sv = POPs;
+ assert(SvTYPE(sv) == SVt_PVMG);
+ assert(SvMAGIC(sv));
+ assert(SvMAGIC(sv)->mg_type == PERL_MAGIC_lvref);
+ itervar = (void *)sv;
+ cxtype |= CXp_FOR_LVREF;
+ }
if (PL_op->op_private & OPpITER_DEF)
cxtype |= CXp_FOR_DEF;
@@ -2133,6 +2141,8 @@ PP(pp_enteriter)
if (SvTYPE(maybe_ary) != SVt_PVAV) {
dPOPss;
SV * const right = maybe_ary;
+ if (UNLIKELY(cxtype & CXp_FOR_LVREF))
+ DIE(aTHX_ "Assigned value is not a reference");
SvGETMAGIC(sv);
SvGETMAGIC(right);
if (RANGE_IS_NUMERIC(sv,right)) {