In perl.git, the branch blead has been updated

<https://perl5.git.perl.org/perl.git/commitdiff/fd77b29b3be4108adb4a74b9c274599eaf228cb3?hp=a8e51187c21fee8697b9299b5303d90883b1eba9>

- Log -----------------------------------------------------------------
commit fd77b29b3be4108adb4a74b9c274599eaf228cb3
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Fri Jan 19 13:47:53 2018 -0800

    Don’t vivify elems when putting array on stack
    
    6661956a2 was a little too powerful, and, in addition to fixing the
    bug that @_ did not properly alias nonexistent elements, also broke
    other uses of nonexistent array elements.  (See the tests added.)
    
    This commit changes it so that putting @a on the stack does not vivify
    all ‘holes’ in @a, but creates defelem (deferred element) scalars, but
    only in lvalue context.

commit bcfce88b64155612fcd6af40e88805fe32c25b7f
Author: Father Chrysostomos <spr...@cpan.org>
Date:   Fri Jan 19 12:41:15 2018 -0800

    Apply the mod flag to @a in \(@a)
    
    The next commit will depend on it.

-----------------------------------------------------------------------

Summary of changes:
 op.c         | 12 ++++++++++--
 pp_hot.c     | 14 +++++++++++---
 t/op/array.t | 33 ++++++++++++++++++++++++++++++++-
 3 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/op.c b/op.c
index 2b87f9c781..373822a349 100644
--- a/op.c
+++ b/op.c
@@ -4081,7 +4081,10 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
     case OP_RV2HV:
        if (type == OP_REFGEN && o->op_flags & OPf_PARENS) {
            PL_modcount = RETURN_UNLIMITED_NUMBER;
-           return o;           /* Treat \(@foo) like ordinary list. */
+           /* Treat \(@foo) like ordinary list, but still mark it as modi-
+              fiable since some contexts need to know.  */
+           o->op_flags |= OPf_MOD;
+           return o;
        }
        /* FALLTHROUGH */
     case OP_RV2GV:
@@ -4146,7 +4149,12 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags)
     case OP_PADHV:
        PL_modcount = RETURN_UNLIMITED_NUMBER;
        if (type == OP_REFGEN && o->op_flags & OPf_PARENS)
-           return o;           /* Treat \(@foo) like ordinary list. */
+       {
+           /* Treat \(@foo) like ordinary list, but still mark it as modi-
+              fiable since some contexts need to know.  */
+           o->op_flags |= OPf_MOD;
+           return o;
+       }
        if (scalar_mod_type(o, type))
            goto nomod;
        if ((o->op_flags & OPf_WANT) != OPf_WANT_SCALAR
diff --git a/pp_hot.c b/pp_hot.c
index d479ecf218..1bc453a457 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1163,8 +1163,12 @@ S_pushav(pTHX_ AV* const av)
     if (UNLIKELY(SvRMAGICAL(av))) {
         PADOFFSET i;
         for (i=0; i < (PADOFFSET)maxarg; i++) {
-            SV ** const svp = av_fetch(av, i, TRUE);
-            SP[i+1] = svp ? *svp : &PL_sv_undef;
+            SV ** const svp = av_fetch(av, i, FALSE);
+            SP[i+1] = LIKELY(svp)
+                       ? *svp
+                       : UNLIKELY(PL_op->op_flags & OPf_MOD)
+                          ? newSVavdefelem(av,i,1)
+                          : &PL_sv_undef;
         }
     }
     else {
@@ -1173,7 +1177,11 @@ S_pushav(pTHX_ AV* const av)
             SV *sv = AvARRAY(av)[i];
            if (!LIKELY(sv))
                AvARRAY(av)[i] = sv = newSV(0);
-           SP[i+1] = sv;
+           SP[i+1] = LIKELY(sv)
+                       ? sv
+                       : UNLIKELY(PL_op->op_flags & OPf_MOD)
+                          ? newSVavdefelem(av,i,1)
+                          : &PL_sv_undef;
         }
     }
     SP += maxarg;
diff --git a/t/op/array.t b/t/op/array.t
index 3d9b9d7900..9d0bfad4ef 100644
--- a/t/op/array.t
+++ b/t/op/array.t
@@ -6,7 +6,7 @@ BEGIN {
     set_up_inc('.', '../lib');
 }
 
-plan (179);
+plan (185);
 
 #
 # @foo, @bar, and @ary are also used from tie-stdarray after tie-ing them
@@ -595,4 +595,35 @@ $#a = -1; $#a++;
     is join("", @r), "55", "lazy element creation with foreach";
 }
 
+{ # Some things broken by the initial fix for #8910
+    (\my @a)->$#*++;
+    my @b = @a;
+    ok !exists $a[0], 'copying an array via = does not vivify elements';
+    delete $a[0];
+    @a[1..5] = 1..5;
+    $#a++;
+    my $count;
+    my @existing_elements = map { exists $a[$count++] ? $_ : () } @a;
+    is join(",", @existing_elements), "1,2,3,4,5",
+       'map {} @a does not vivify elements';
+    $#a = -1;
+    {local $a[3] = 12; my @foo=@a};
+    is @a, 0,'unwinding localization of elem past end of array shrinks it';
+
+    # Again, but with a package array
+    package tmp; (\our @a)->$#*++; package main;
+    my @b = @a;
+    ok !exists $a[0], 'copying an array via = does not vivify elements';
+    delete $a[0];
+    @a[1..5] = 1..5;
+    $#a++;
+    my $count;
+    my @existing_elements = map { exists $a[$count++] ? $_ : () } @a;
+    is join(",", @existing_elements), "1,2,3,4,5",
+       'map {} @a does not vivify elements';
+    $#a = -1;
+    {local $a[3] = 12; my @foo=@a};
+    is @a, 0, 'unwinding localization of elem past end of array shrinks it'
+}
+
 "We're included by lib/Tie/Array/std.t so we need to return something true";

-- 
Perl5 Master Repository

Reply via email to