In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/02960b52b40b494fa4f6e1be81db5f3459ab91a9?hp=622c613e12cef84c93c5df207a321fe13d0f2a7f>

- Log -----------------------------------------------------------------
commit 02960b52b40b494fa4f6e1be81db5f3459ab91a9
Author: David Mitchell <[email protected]>
Date:   Fri Aug 4 15:17:44 2017 +0100

    set SVs_PADTMP flag on PL_sv_zero
    
    Where an op in scalar but not boolean context returns &PL_sv_zero as a
    more efficient way of doing sv_2mortal(newSViv(0)), the returned value
    must be mutable. For example
    
        my @a = ();
        my $r = \ scalar grep $_ == 1, @a;
        $$r += 10;
    
    By setting the SVs_PADTMP flag, this forces pp_srefgen() and similar to
    make a mortal copy of &PL_sv_zero.
    
    This kind of defeats the original optimisation, but the copy only kicks
    in under certain circumstances, whereas the newSViv(0) approach would
    create a new mortal every time.
    
    See RT #78288 for where FC suggested the problem and the solution.
-----------------------------------------------------------------------

Summary of changes:
 sv.c       |  3 ++-
 t/op/ref.t | 14 +++++++++++++-
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/sv.c b/sv.c
index 055f891016..087fc73f89 100644
--- a/sv.c
+++ b/sv.c
@@ -15927,7 +15927,8 @@ Perl_init_constants(pTHX)
     SvREFCNT(&PL_sv_zero)      = SvREFCNT_IMMORTAL;
     SvFLAGS(&PL_sv_zero)       = SVt_PVNV|SVf_READONLY|SVf_PROTECT
                                  |SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK
-                                 |SVp_POK|SVf_POK;
+                                 |SVp_POK|SVf_POK
+                                  |SVs_PADTMP;
 
     SvPV_set(&PL_sv_no, (char*)PL_No);
     SvCUR_set(&PL_sv_no, 0);
diff --git a/t/op/ref.t b/t/op/ref.t
index a0caf3868b..19163ef476 100644
--- a/t/op/ref.t
+++ b/t/op/ref.t
@@ -8,7 +8,7 @@ BEGIN {
 
 use strict qw(refs subs);
 
-plan(253);
+plan(254);
 
 # Test this first before we extend the stack with other operations.
 # This caused an asan failure due to a bad write past the end of the stack.
@@ -862,6 +862,18 @@ for ("4eounthouonth") {
     is $r, 0, 'if (ref $obj0) else';
 }
 
+{
+    # RT #78288
+    # if an op returns &PL_sv_zero rather than newSViv(0), the
+    # value should be mutable. So ref (via the PADTMP flag) should
+    # make a mutable copy
+
+    my @a = ();
+    my $r = \ scalar grep $_ == 1, @a;
+    $$r += 10;
+    is $$r, 10, "RT #78288 - mutable PL_sv_zero copy";
+}
+
 
 # RT#130861: heap-use-after-free in pp_rv2sv, from asan fuzzing
 SKIP: {

--
Perl5 Master Repository

Reply via email to