summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2015-12-08 11:19:48 +1100
committerTony Cook <tony@develop-help.com>2016-01-11 08:51:16 +1100
commit5c1db5695506e43718a1575bebb1ecf2675e3798 (patch)
treef5708bef7e4f76b7d54e7b4588fc774dbc8b81c1
parentbeb08a1e6d63c1eed4da66e066991eb58afccde7 (diff)
downloadperl-5c1db5695506e43718a1575bebb1ecf2675e3798.tar.gz
[perl #126633] copy anything gmagical on the right
It could retrieve something we're setting on the left.
-rw-r--r--pp_hot.c6
-rw-r--r--t/op/aassign.t9
2 files changed, 11 insertions, 4 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 650f06b756..b80efaef54 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1173,7 +1173,7 @@ S_aassign_copy_common(pTHX_ SV **firstlelem, SV **lastlelem,
svr = *relem;
assert(svr);
- if (UNLIKELY(SvFLAGS(svr) & SVf_BREAK || copy_all)) {
+ if (UNLIKELY(SvFLAGS(svr) & (SVf_BREAK|SVs_GMG) || copy_all)) {
#ifdef DEBUGGING
if (fake) {
@@ -1265,6 +1265,10 @@ PP(pp_aassign)
/* at least 2 LH and RH elements, or commonality isn't an issue */
if (firstlelem < lastlelem && firstrelem < lastrelem) {
+ for (relem = firstrelem+1; relem <= lastrelem; relem++) {
+ if (SvGMAGICAL(*relem))
+ goto do_scan;
+ }
for (lelem = firstlelem; lelem <= lastlelem; lelem++) {
if (*lelem && SvSMAGICAL(*lelem))
goto do_scan;
diff --git a/t/op/aassign.t b/t/op/aassign.t
index d6a1a42321..03cc84c3f4 100644
--- a/t/op/aassign.t
+++ b/t/op/aassign.t
@@ -345,9 +345,10 @@ SKIP: {
{ # magic handling, see #126633
use v5.22;
+ my $set;
package ArrayProxy {
sub TIEARRAY { bless [ $_[1] ] }
- sub STORE { $_[0][0]->[$_[1]] = $_[2] }
+ sub STORE { $_[0][0]->[$_[1]] = $_[2]; $set = 1 }
sub FETCH { $_[0][0]->[$_[1]] }
sub CLEAR { @{$_[0][0]} = () }
sub EXTEND {}
@@ -363,9 +364,7 @@ SKIP: {
@real = @base;
@real[0, 1] = @proxy[1, 0];
is($real[0], "b", "tied right first");
- { local $::TODO = "#126633";
is($real[1], "a", "tied right second");
- }
@real = @base;
@proxy[0, 1] = @proxy[1, 0];
is($real[0], "b", "tied both first");
@@ -379,6 +378,10 @@ SKIP: {
@real = @base;
($temp, @proxy) = @proxy[1, 0];
is($real[0], "a", "scalar/array tied both");
+ $set = 0;
+ my $orig;
+ ($proxy[0], $orig) = (1, $set);
+ is($orig, 0, 'previous value of $set');
}
done_testing();