This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_negate: Don’t treat nummified str as num
authorFather Chrysostomos <sprout@cpan.org>
Wed, 6 Jun 2012 05:38:12 +0000 (22:38 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 7 Jun 2012 15:18:54 +0000 (08:18 -0700)
commit8a5decd86e575fa785c97ea9b6642e4e87294101
treebe1bfb6db609d72eb0171641031f4a783f48705c
parent01f91bf275559c4ad5a42efe7848a0db00ceb317
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
pp.c
t/op/negate.t