summaryrefslogtreecommitdiff
path: root/op.c
diff options
context:
space:
mode:
authorArtur Bergman <sky@nanisky.com>2003-03-04 01:01:07 +0000
committerArtur Bergman <sky@nanisky.com>2003-03-04 01:01:07 +0000
commit3b1c21fabed159100271bd60bac3f870f5ac16af (patch)
tree964a49425c97f3e07139b6c00a0be98f76e90933 /op.c
parentbf61ac64f9c44081613e3d1b479639fda606e19f (diff)
downloadperl-3b1c21fabed159100271bd60bac3f870f5ac16af.tar.gz
Fixes bug #15654 bizarre constant mangling in 5.8.0
What happened was that a constant was freed, the pad released but the pad slot still held the SV, when pad slot was reallocated to be a target for a stringify, it did a sv_setpv on the target and the original SV was wiped out. When this SV was later on to new places using the constant, they got the wrong value. By replacing pad_free with pad_swipe for these cases, we won't have such a problem. (pad_swipe also removes the pointer to the original SV). p4raw-id: //depot/perl@18820
Diffstat (limited to 'op.c')
-rw-r--r--op.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/op.c b/op.c
index 2a7583eb7d..f0156187a7 100644
--- a/op.c
+++ b/op.c
@@ -299,6 +299,18 @@ Perl_op_clear(pTHX_ OP *o)
case OP_CONST:
SvREFCNT_dec(cSVOPo->op_sv);
cSVOPo->op_sv = Nullsv;
+#ifdef USE_ITHREADS
+ /** Bug #15654
+ Even if op_clear does a pad_free for the target of the op,
+ pad_free doesn't actually remove the sv that exists in the bad
+ instead it lives on. This results in that it could be reused as
+ a target later on when the pad was reallocated.
+ **/
+ if(o->op_targ) {
+ pad_swipe(o->op_targ,1);
+ o->op_targ = 0;
+ }
+#endif
break;
case OP_GOTO:
case OP_NEXT: