diff options
author | Father Chrysostomos <sprout@cpan.org> | 2018-02-18 16:12:11 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2018-02-18 16:29:35 -0800 |
commit | 9ef753fe465d865deeba96157242bc98c0afe412 (patch) | |
tree | 15d7e5eb8eae642b4fccd1872bf40e80f3e9eb1c /t | |
parent | 7406cffe8ec122fcc2500115f8ed1742385893e1 (diff) | |
download | perl-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.t | 31 |
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"; |