summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2018-02-18 16:12:11 -0800
committerFather Chrysostomos <sprout@cpan.org>2018-02-18 16:29:35 -0800
commit9ef753fe465d865deeba96157242bc98c0afe412 (patch)
tree15d7e5eb8eae642b4fccd1872bf40e80f3e9eb1c /t
parent7406cffe8ec122fcc2500115f8ed1742385893e1 (diff)
downloadperl-9ef753fe465d865deeba96157242bc98c0afe412.tar.gz
Fix ary shifting when sparse ary is passed to sub
This commit fixes #132729 in the specific case where a nonexistent element within a sparse array is passed to a subroutine. Prior to this commit, some_sub($sparse_array[$n]) where $n <= $#sparse_array and the element does not exist, would exhi- bit erroneous behaviour if some_sub shifted or unshifted the original @sparse_array. Any ‘holes’ (nonexistent elements) in the array would show up in @_ as deferred element (defelem) scalars, magic scalars that remember their index in the array. This index is not updated and gets out of synch when the array is shifted. This commit fixes the bug for elements within the array by using the new ‘nonelem’ magic introduced a few commits ago. It stores within the array a magic scalar that is marked as being nonexistent. It also reduced the number of scalars that need to be created if such a sub call happens repeatedly.
Diffstat (limited to 't')
-rw-r--r--t/op/array.t31
1 files changed, 30 insertions, 1 deletions
diff --git a/t/op/array.t b/t/op/array.t
index 04b87bd59a..6370a9f072 100644
--- a/t/op/array.t
+++ b/t/op/array.t
@@ -6,7 +6,7 @@ BEGIN {
set_up_inc('.', '../lib');
}
-plan (190);
+plan (194);
#
# @foo, @bar, and @ary are also used from tie-stdarray after tie-ing them
@@ -658,5 +658,34 @@ $#a = -1; $#a++;
is "[@a]", "[7 3 1]",
'non-elems read from magical @a do not lose their position';
}
+# perl #132729, as it applies to ‘holes’ in an array passed to a sub
+# individually
+{
+ my @a;
+ $a[1] = 1;
+ sub { unshift @a, 7; $_[0] = 3; }->($a[0]);
+ is "[@a]", "[7 3 1]",
+ 'holes passed to sub do not lose their position (multideref)';
+ @a = ();
+ $#a++; # make it magical
+ $a[1] = 1;
+ sub { unshift @a, 7; $_[0] = 3; }->($a[0]);
+ is "[@a]", "[7 3 1]",
+ 'holes passed to sub do not lose their position (multideref, mg)';
+}
+{
+ # Again, with aelem, not multideref
+ my @a;
+ $a[1] = 1;
+ sub { unshift @a, 7; $_[0] = 3; }->($a[${\0}]);
+ is "[@a]", "[7 3 1]",
+ 'holes passed to sub do not lose their position (aelem)';
+ @a = ();
+ $#a++; # make it magical
+ $a[1] = 1;
+ sub { unshift @a, 7; $_[0] = 3; }->($a[${\0}]);
+ is "[@a]", "[7 3 1]",
+ 'holes passed to sub do not lose their position (aelem, mg)';
+}
"We're included by lib/Tie/Array/std.t so we need to return something true";