In perl.git, the branch blead has been updated <https://perl5.git.perl.org/perl.git/commitdiff/b97fe865adca6799771c93fc17e9f36ae7272e72?hp=328d9079796a9f9f8dfb4813f36e50e8a77a0748>
- Log ----------------------------------------------------------------- commit b97fe865adca6799771c93fc17e9f36ae7272e72 Author: David Mitchell <da...@iabyn.com> Date: Mon Nov 5 12:29:27 2018 +0000 Don't localise array / hash slice ref assignment RT #133538 The experimental ref assignment aliasing feature, when applied to array or hash slices, was treating the slice as if it was always localized; e.g. \(@a[3,5,7]) = \(....); was being interpreted as local \(@a[3,5,7]) = \(....); The fix is simple: check for the OPpLVAL_INTRO flag actually being set on the op, rather than unconditionally localising the array/hash elements. ----------------------------------------------------------------------- Summary of changes: pp.c | 10 ++++++---- t/op/lvref.t | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/pp.c b/pp.c index cfa343fbbb..6d432acd31 100644 --- a/pp.c +++ b/pp.c @@ -6599,10 +6599,12 @@ PP(pp_lvrefslice) while (++MARK <= SP) { SV * const elemsv = *MARK; - if (SvTYPE(av) == SVt_PVAV) - S_localise_aelem_lval(aTHX_ av, elemsv, can_preserve); - else - S_localise_helem_lval(aTHX_ (HV *)av, elemsv, can_preserve); + if (UNLIKELY(localizing)) { + if (SvTYPE(av) == SVt_PVAV) + S_localise_aelem_lval(aTHX_ av, elemsv, can_preserve); + else + S_localise_helem_lval(aTHX_ (HV *)av, elemsv, can_preserve); + } *MARK = sv_2mortal(newSV_type(SVt_PVMG)); sv_magic(*MARK,(SV *)av,PERL_MAGIC_lvref,(char *)elemsv,HEf_SVKEY); } diff --git a/t/op/lvref.t b/t/op/lvref.t index 28adc6ad23..3d5e952fb0 100644 --- a/t/op/lvref.t +++ b/t/op/lvref.t @@ -4,7 +4,7 @@ BEGIN { set_up_inc("../lib"); } -plan 156; +plan 164; eval '\$x = \$y'; like $@, qr/^Experimental aliasing via reference not enabled/, @@ -603,3 +603,39 @@ pass("RT #123821"); eval q{sub{\@0[0]=0};}; pass("RT #128252"); } + +# RT #133538 slices were inadvertently always localising + +{ + use feature 'refaliasing'; + no warnings 'experimental'; + + my @src = (100,200,300); + + my @a = (1,2,3); + my %h = qw(one 10 two 20 three 30); + + { + use feature 'declared_refs'; + local \(@a[0,1,2]) = \(@src); + local \(@h{qw(one two three)}) = \(@src); + $src[0]++; + is("@a", "101 200 300", "rt #133538 \@a aliased"); + is("$h{one} $h{two} $h{three}", "101 200 300", "rt #133538 %h aliased"); + } + is("@a", "1 2 3", "rt #133538 \@a restored"); + is("$h{one} $h{two} $h{three}", "10 20 30", "rt #133538 %h restored"); + + { + \(@a[0,1,2]) = \(@src); + \(@h{qw(one two three)}) = \(@src); + $src[0]++; + is("@a", "102 200 300", "rt #133538 \@a aliased try 2"); + is("$h{one} $h{two} $h{three}", "102 200 300", + "rt #133538 %h aliased try 2"); + } + $src[2]++; + is("@a", "102 200 301", "rt #133538 \@a still aliased"); + is("$h{one} $h{two} $h{three}", "102 200 301", "rt #133538 %h still aliased"); + +} -- Perl5 Master Repository