summaryrefslogtreecommitdiff
path: root/t/op/negate.t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-06-05 22:38:12 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-06-07 08:18:54 -0700
commit8a5decd86e575fa785c97ea9b6642e4e87294101 (patch)
treebe1bfb6db609d72eb0171641031f4a783f48705c /t/op/negate.t
parent01f91bf275559c4ad5a42efe7848a0db00ceb317 (diff)
downloadperl-8a5decd86e575fa785c97ea9b6642e4e87294101.tar.gz
pp_negate: Don’t treat nummified str as num
I think it’s a bug that this prints 0: $ ./perl -lIlib -MDevel::Peek -e '$x = "dogs"; 0+$x; Dump $x; print -$x' SV = PVNV(0x802340) at 0x821b90 REFCNT = 1 FLAGS = (POK,pIOK,pNOK,pPOK) IV = 0 NV = 0 PV = 0x301620 "dogs"\0 CUR = 4 LEN = 16 0 This variable is a string, not a number. The number 0 is just a cached value. It lacks the IOK flag precisely because the IV is not representative of the actual value of the scalar. This logic here is a little bit odd: if( !SvNIOK( sv ) && looks_like_number( sv ) ){ SvIV_please( sv ); } if ((flags & SVf_IOK) || ((flags & (SVp_IOK | SVp_NOK)) == SVp_IOK)) { SvIV_please sets the flags on sv but then they are ignored when check- ing for integrality. To fix the bug mentioned above, I had to change this logic to use sv directly, rather than the saved flags. That meant that this bug was also fixed at the same time, since the integer code is no longer bypassed when it is SvIV_please that sets the integer flags: $ ./perl -Ilib -le 'print -97656250000000000' -97656250000000000 $ ./perl -Ilib -le 'print -"97656250000000000"' -9.765625e+16
Diffstat (limited to 't/op/negate.t')
-rw-r--r--t/op/negate.t11
1 files changed, 9 insertions, 2 deletions
diff --git a/t/op/negate.t b/t/op/negate.t
index 8a0ef2b59c..62dc418def 100644
--- a/t/op/negate.t
+++ b/t/op/negate.t
@@ -6,7 +6,7 @@ BEGIN {
require './test.pl';
}
-plan tests => 16;
+plan tests => 18;
# Some of these will cause warnings if left on. Here we're checking the
# functionality, not the warnings.
@@ -28,4 +28,11 @@ is(-bareword, "-bareword", "Negation of bareword treated like a string");
is(- -bareword, "+bareword", "Negation of -bareword returns string +bareword");
is(-" -10", 10, "Negation of a whitespace-lead numeric string");
is(-" -10.0", 10, "Negation of a whitespace-lead decimal string");
-is(-" -10foo", 10, "Negation of a whitespace-lead sting starting with a numeric")
+is(-" -10foo", 10,
+ "Negation of a whitespace-lead sting starting with a numeric");
+
+$x = "dogs";
+()=0+$x;
+is -$x, '-dogs', 'cached numeric value does not sabotage string negation';
+
+is(-"97656250000000000", -97656250000000000, '-bigint vs -"bigint"');