Stop op freeing from interfering with sub(){42} mutability
authorFather Chrysostomos <sprout@cpan.org>
Wed, 24 Jul 2013 15:39:01 +0000 (08:39 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 26 Jul 2013 06:48:03 +0000 (23:48 -0700)
The problem is that when an OP_CONST is freed, it calls pad_swipe,
which clears the PADTMP flag when removing the SV from the pad.  Since
PADTMP no longer necessarily means ‘in a pad’, we shouldn’t turn
this flag off.

pad.c
t/op/sub.t

diff --git a/pad.c b/pad.c
index 76d8aa4..0bf65cd 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -1638,8 +1638,6 @@ Perl_pad_swipe(pTHX_ PADOFFSET po, bool refadjust)
                "Pad 0x%"UVxf"[0x%"UVxf"] swipe:   %ld\n",
                PTR2UV(PL_comppad), PTR2UV(PL_curpad), (long)po));
 
-    if (PL_curpad[po] && !SvPADMY(PL_curpad[po]))
-       SvPADTMP_off(PL_curpad[po]);
     if (refadjust)
        SvREFCNT_dec(PL_curpad[po]);
 
index 53eae4a..fc04ac8 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan( tests => 26 );
+plan( tests => 27 );
 
 sub empty_sub {}
 
@@ -140,6 +140,12 @@ eval { ${\not_constantm}++ };
 is $@, "", 'my sub (){42} returns a mutable value';
 eval { ${\not_constantmr}++ };
 is $@, "", 'my sub (){ return 42 } returns a mutable value';
+is eval {
+    sub Crunchy () { 1 }
+    sub Munchy { $_[0] = 2 }
+    eval "Crunchy"; # test that freeing this op does not turn off PADTMP
+    Munchy(Crunchy);
+} || $@, 2, 'freeing ops does not make sub(){42} immutable';
 
 # [perl #79908]
 {