under useithreads, constant pad entries could inadvertently be
Gurusamy Sarathy [Fri, 28 Apr 2000 03:07:54 +0000 (03:07 +0000)]
shared across threads (from Eric Blood <eblood@xmission.com>);
added Eric's test case to testsuite

p4raw-id: //depot/perl@5979

op.c
t/op/misc.t

diff --git a/op.c b/op.c
index 7ca60ae..681efae 100644 (file)
--- a/op.c
+++ b/op.c
@@ -6433,9 +6433,18 @@ Perl_peep(pTHX_ register OP *o)
             * for reference counts, sv_upgrade() etc. */
            if (cSVOP->op_sv) {
                PADOFFSET ix = pad_alloc(OP_CONST, SVs_PADTMP);
-               SvREFCNT_dec(PL_curpad[ix]);
-               SvPADTMP_on(cSVOPo->op_sv);
-               PL_curpad[ix] = cSVOPo->op_sv;
+               if (SvPADTMP(cSVOPo->op_sv)) {
+                   /* If op_sv is already a PADTMP then it is being used by
+                    * another pad, so make a copy. */
+                   sv_setsv(PL_curpad[ix],cSVOPo->op_sv);
+                   SvREADONLY_on(PL_curpad[ix]);
+                   SvREFCNT_dec(cSVOPo->op_sv);
+               }
+               else {
+                   SvREFCNT_dec(PL_curpad[ix]);
+                   SvPADTMP_on(cSVOPo->op_sv);
+                   PL_curpad[ix] = cSVOPo->op_sv;
+               }
                cSVOPo->op_sv = Nullsv;
                o->op_targ = ix;
            }
index ef3be30..55f459d 100755 (executable)
@@ -551,3 +551,10 @@ my $x = "foo";
 { f } continue { print $x, "\n" }
 EXPECT
 foo
+########
+sub C () { 1 }
+sub M { $_[0] = 2; }
+eval "C";
+M(C);
+EXPECT
+Modification of a read-only value attempted at - line 2.