diff options
author | Ben Morrow <ben@morrow.me.uk> | 2010-08-20 18:35:58 +0100 |
---|---|---|
committer | Jan Dubois <jand@activestate.com> | 2010-08-20 15:57:11 -0700 |
commit | d88e091f660036722622a815efa9ef3779605ea6 (patch) | |
tree | 653a33d8dc75118b4598d1f9190659693f994f6b | |
parent | ecf9cdab78811498b3ffea48cfdfb09f678050d2 (diff) | |
download | perl-d88e091f660036722622a815efa9ef3779605ea6.tar.gz |
Fix my $x = 3; $x = length(undef);.
Assignment of length() to a lexical is optimized by passing the
assigned-to variable as TARG, avoiding a pp_padsv and pp_sassign.
9f621b which changed length(undef) to return undef didn't take this into
account, and used SETs (which doesn't set TARG), so the code above left
$x == 3.
-rw-r--r-- | pp.c | 9 | ||||
-rw-r--r-- | t/op/length.t | 17 |
2 files changed, 22 insertions, 4 deletions
@@ -3105,8 +3105,10 @@ PP(pp_length) = sv_2pv_flags(sv, &len, SV_UNDEF_RETURNS_NULL|SV_CONST_RETURN|SV_GMAGIC); - if (!p) - SETs(&PL_sv_undef); + if (!p) { + sv_setsv(TARG, &PL_sv_undef); + SETTARG; + } else if (DO_UTF8(sv)) { SETi(utf8_length((U8*)p, (U8*)p + len)); } @@ -3119,7 +3121,8 @@ PP(pp_length) else SETi(sv_len(sv)); } else { - SETs(&PL_sv_undef); + sv_setsv_nomg(TARG, &PL_sv_undef); + SETTARG; } RETURN; } diff --git a/t/op/length.t b/t/op/length.t index c73d4c5a5a..705b9d5a0c 100644 --- a/t/op/length.t +++ b/t/op/length.t @@ -6,7 +6,7 @@ BEGIN { @INC = '../lib'; } -plan (tests => 30); +plan (tests => 36); print "not " unless length("") == 0; print "ok 1\n"; @@ -193,6 +193,21 @@ my $uo = bless [], 'U'; is(length($uo), undef, "Length of overloaded reference"); +my $ul = 3; +is(($ul = length(undef)), undef, + "Returned length of undef with result in TARG"); +is($ul, undef, "Assigned length of undef with result in TARG"); + +$ul = 3; +is(($ul = length($u)), undef, + "Returned length of tied undef with result in TARG"); +is($ul, undef, "Assigned length of tied undef with result in TARG"); + +$ul = 3; +is(($ul = length($uo)), undef, + "Returned length of overloaded undef with result in TARG"); +is($ul, undef, "Assigned length of overloaded undef with result in TARG"); + # ok(!defined $uo); Turns you can't test this. FIXME for pp_defined? is($warnings, 0, "There were no warnings"); |