diff options
author | David Mitchell <davem@iabyn.com> | 2010-09-08 16:53:10 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2010-09-08 16:53:10 +0100 |
commit | f83b46a0147ba6f476add85d17f61a7e7fb00f21 (patch) | |
tree | 0dcc25c8bf4f78496319fc13634d851282f3a960 /pp_ctl.c | |
parent | aafca5257dfefe4cf2a531c79cadea21a566f9c3 (diff) | |
download | perl-f83b46a0147ba6f476add85d17f61a7e7fb00f21.tar.gz |
bad things happened with for $x (...) { *x = *y }
fix for [perl #21469]:
since the GP may be pulled from under us and freed, coredumps and strange
things can happen.
Fix this by storing a pointer to the GV in the loop block, rather than a
pointer to the GvSV slot. The ITHREADS variant already stores GV rather
than than &GvSV; extend this to non-threaded builds too.
Also, for both threaded and non-threaded, it used to push &GvSV on the
save stack. Fix this by introducing a new save type, SAVEt_GVSV.
This behaves similarly to SAVEt_SV, but without magic get/set.
This means that
for $package_var (...)
is now close in behaviour to
local $package_var = ...
(except for the magic bit).
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 7 |
1 files changed, 2 insertions, 5 deletions
@@ -1967,13 +1967,10 @@ PP(pp_enteriter) } else { /* symbol table variable */ GV * const gv = MUTABLE_GV(POPs); - SV** svp = &GvSV(gv); SAVEGENERICSV(*svp); + SV** svp = &GvSV(gv); + save_pushptrptr(gv, SvREFCNT_inc(*svp), SAVEt_GVSV); *svp = newSV(0); -#ifdef USE_ITHREADS itervar = (void *)gv; -#else - itervar = (void *)svp; -#endif } if (PL_op->op_private & OPpITER_DEF) |