diff options
author | David Mitchell <davem@iabyn.com> | 2020-08-11 11:55:46 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2020-08-11 16:14:21 +0100 |
commit | 5b354d2a8a6fea46c62048464c6722560cb1c907 (patch) | |
tree | 3f3defd530bd7ca6b5dec4570e8703edf22ad8bc /op.c | |
parent | 1ad5a39ccaca372a3b35f5a76e16aa2aacab104a (diff) | |
download | perl-5b354d2a8a6fea46c62048464c6722560cb1c907.tar.gz |
list assign in list context was over-optimising
GH #17816
This code:
my $x = 1;
print (($x, undef) = (2 => $x));
was printing "22" when it should have been printing "21".
An optimisation skips the 'common values on both sides' test
when the LHS of an assign only contains a single var; as the example
above shows, this is not sufficient.
This was broken by v5.23.1-202-g808ce55782
This commit fixes it by counting undef's on the LHS towards the var
count if they don't appear first.
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 10 |
1 files changed, 7 insertions, 3 deletions
@@ -15679,11 +15679,15 @@ S_aassign_scan(pTHX_ OP* o, bool rhs, int *scalars_p) goto do_next; case OP_UNDEF: - /* undef counts as a scalar on the RHS: - * (undef, $x) = ...; # only 1 scalar on LHS: always safe + /* undef on LHS following a var is significant, e.g. + * my $x = 1; + * @a = (($x, undef) = (2 => $x)); + * # @a shoul be (2,1) not (2,2) + * + * undef on RHS counts as a scalar: * ($x, $y) = (undef, $x); # 2 scalars on RHS: unsafe */ - if (rhs) + if ((!rhs && *scalars_p) || rhs) (*scalars_p)++; flags = AAS_SAFE_SCALAR; break; |