From 7d779b236fc2cb0c2dbe324bda777c76494a71a5 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Thu, 7 Apr 2011 11:44:15 -0700 Subject: [PATCH] [perl #87708] $tied == $tied MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This is only part of #87708. This fixes the + operator outside of any ‘use integer’ scope when the same tied scalar is used for both operands and returns two different values. Before this commit, get-magic would be called only once and the same value used. In 5.12.x it just worked. I tried modifying pp_eq throughout to take this case into account, but it made the most common cases slightly slower, presumably because of the extra checks. So this follows the same temp sv method that I used for pp_add (in 4c3ac4b and 837c879), which, though slowing down this edge cases due to the extra allocation, leaves the most common cases just as fast. (And, in case my benchmarks were unreliably [not unlikely], this method is also safer, as it has less chance of getting different code paths wrong.) --- pp_hot.c | 12 ++++++++++++ t/lib/warnings/9uninit | 11 ++++++++--- t/op/tie_fetch_count.t | 5 +---- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/pp_hot.c b/pp_hot.c index 06b837b..b6b8851 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -342,6 +342,18 @@ PP(pp_eq) RETURN; } #endif + if (TOPs == TOPm1s && SvGMAGICAL(TOPs)) { + SV * const svl = sv_newmortal(); + /* Print the uninitialized warning now, so it includes the vari- + able name. */ + if (!SvOK(TOPs)) { + if (ckWARN(WARN_UNINITIALIZED)) report_uninit(TOPs); + sv_setiv(svl,0); + } + else sv_setsv_flags(svl, TOPs, 0); + SvGETMAGIC(TOPs); + TOPm1s = svl; + } #ifdef PERL_PRESERVE_IVUV SvIV_please_nomg(TOPs); if (SvIOK(TOPs)) { diff --git a/t/lib/warnings/9uninit b/t/lib/warnings/9uninit index 1dcee79..4472db4 100644 --- a/t/lib/warnings/9uninit +++ b/t/lib/warnings/9uninit @@ -693,12 +693,17 @@ sub TIESCALAR{bless[]} sub FETCH { undef } tie my $m1, ""; -my $v = $m1 + $m1; +my $v; +$v = $m1 + $m1; +$v = $m1 - $m1; no warnings; $v = $m1 + $m1; +$v = $m1 - $m1; EXPECT -Use of uninitialized value $m1 in addition (+) at - line 6. -Use of uninitialized value $m1 in addition (+) at - line 6. +Use of uninitialized value $m1 in addition (+) at - line 7. +Use of uninitialized value $m1 in addition (+) at - line 7. +Use of uninitialized value $m1 in subtraction (-) at - line 8. +Use of uninitialized value $m1 in subtraction (-) at - line 8. ######## use warnings 'uninitialized'; my ($m1, $v); diff --git a/t/op/tie_fetch_count.t b/t/op/tie_fetch_count.t index be339cd..df1c0fe 100644 --- a/t/op/tie_fetch_count.t +++ b/t/op/tie_fetch_count.t @@ -225,10 +225,7 @@ my $todo = 'bug #87708'; bin_test '|' , 1, 2, 3; } bin_test '.' , 1, 2, 12; -{ - local $TODO = $todo ; - bin_test '==', 1, 2, ""; -} +bin_test '==', 1, 2, ""; bin_test '+' , 1, 2, 3; bin_int_test '*' , 2, 3, 6; bin_int_test '/' , 10, 2, 5; -- 1.8.3.1