pp_negate: Support magic big ints as strings
authorFather Chrysostomos <sprout@cpan.org>
Thu, 7 Jun 2012 06:05:24 +0000 (23:05 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 7 Jun 2012 15:18:55 +0000 (08:18 -0700)
-$1 was treating $1 as a float even if the string consisted of an
integer, due to incorrect flag checks.  It was doing the same things
with tied variables returning str+int dualvars.

Simply checking whether the privates flags consist solely of SVp_IOK
(which works for tie variables returning pure integers--so I wasn’t
entirely wrong in adding that logic a few commits ago), isn’t suffi-
cient. For gmagical variables that have already had get-magic called
on them, the private flags are equivalent to public flags for other
variables.

pp.c
t/op/negate.t

diff --git a/pp.c b/pp.c
index f7ea741..811d185 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -2161,8 +2161,8 @@ PP(pp_negate)
            SvIV_please_nomg( sv );
         }   
 
-       if (SvIOK(sv) || (SvOKp(sv) == SVp_IOK)) {
-           /* It's publicly an integer, or privately just an integer */
+       if (SvIOK(sv) || (SvGMAGICAL(sv) && SvIOKp(sv))) {
+           /* It's publicly an integer */
        oops_its_an_int:
            if (SvIsUV(sv)) {
                if (SvIVX(sv) == IV_MIN) {
index 37987ef..6c355c7 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 22;
+plan tests => 24;
 
 # Some of these will cause warnings if left on.  Here we're checking the
 # functionality, not the warnings.
@@ -40,8 +40,20 @@ $x = "dogs";
 is -$x, '-dogs', 'cached numeric value does not sabotage string negation';
 
 is(-"97656250000000000", -97656250000000000, '-bigint vs -"bigint"');
+"9765625000000000" =~ /(\d+)/;
+is -$1, -"$1", '-$1 vs -"$1" with big int';
 
 $a = "%apples";
 chop($au = "%apples\x{100}");
 is(-$au, -$a, 'utf8 flag makes no difference for string negation');
 is -"\x{100}", 0, '-(non-ASCII) is equivalent to -(punct)';
+
+sub TIESCALAR { bless[] }
+sub STORE { $_[0][0] = $_[1] }
+sub FETCH { $_[0][0] }
+
+tie $t, "";
+$a = "97656250000000000";
+() = 0+$a;
+$t = $a;
+is -$t, -97656250000000000, 'magic str+int dualvar';