From f83b46a0147ba6f476add85d17f61a7e7fb00f21 Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Wed, 8 Sep 2010 16:53:10 +0100 Subject: 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). --- scope.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'scope.c') diff --git a/scope.c b/scope.c index 93ef4b3fc9..046b3387d5 100644 --- a/scope.c +++ b/scope.c @@ -778,9 +778,15 @@ Perl_leave_scope(pTHX_ I32 base) *(char**)ptr = str; } break; + case SAVEt_GVSV: /* scalar slot in GV */ + value = MUTABLE_SV(SSPOPPTR); + gv = MUTABLE_GV(SSPOPPTR); + ptr = &GvSV(gv); + goto restore_svp; case SAVEt_GENERIC_SVREF: /* generic sv */ value = MUTABLE_SV(SSPOPPTR); ptr = SSPOPPTR; + restore_svp: sv = *(SV**)ptr; *(SV**)ptr = value; SvREFCNT_dec(sv); -- cgit v1.2.1