Skip no-common-vars optimisation for aliases
authorFather Chrysostomos <sprout@cpan.org>
Thu, 18 Sep 2014 23:10:01 +0000 (16:10 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 19 Sep 2014 01:20:50 +0000 (18:20 -0700)
commitff2a62e0c8bedade55bf86a22861a2fe06bb0a16
treec049e3257b21cb049fbbda2a41886fcacd5eec5d
parent4a8cd1baba77cafb21681f12b12c120bdd458938
Skip no-common-vars optimisation for aliases

The ‘no common vars’ optimisation allows perl to copy the values
straight from the rhs to the lhs in a list assignment.

In ($a,$b) = ($c,$d), that means $c gets assigned to $a,
then $d to $b.

If the same variable occurs on both sides of the expression
(($a,$b)=($b,$a)), then it is necessary to make temporary copies of
the variables on the rhs, before assigning them to the left.

If some variables have been aliased to others, then the common vars
detection can be fooled:

    *x = *y;
    $x = 3;
    ($x, $z) = (1, $y);

That assigns 1 to $x, and then goes to assign $y to $z, but $y is
the same as $x, which has just been clobbered.  So 1 gets assigned
instead of 3.

This commit solves this by recording in each typeglob whether the sca-
lar is an alias of a scalar from elsewhere.

If such a glob is encountered, then the entire expression is ‘tainted’
such that list assignments will assume there might be common vars.
embedvar.h
gv.h
intrpvar.h
pp_hot.c
scope.c
scope.h
sv.c
t/op/gv.t