diff options
author | Rick Delaney <rick@consumercontact.com> | 2007-10-06 20:22:14 -0400 |
---|---|---|
committer | Rafael Garcia-Suarez <rgarciasuarez@gmail.com> | 2007-10-07 09:44:22 +0000 |
commit | c781a409e12d3d0d5a289d2e43b9c4e399d30667 (patch) | |
tree | 353c258a9626a807e6eddff5de97df32ce6850b8 /pp.c | |
parent | 88c9ea1eee075fb55dd1fa8e866125da26b560ff (diff) | |
download | perl-c781a409e12d3d0d5a289d2e43b9c4e399d30667.tar.gz |
Re: [perl #46011] overload "0+" doesn't handle integer results
Message-ID: <20071007042214.GH29047@bort.ca>
p4raw-id: //depot/perl@32059
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 34 |
1 files changed, 25 insertions, 9 deletions
@@ -2874,22 +2874,38 @@ PP(pp_int) { dVAR; dSP; dTARGET; tryAMAGICun(int); { - const IV iv = TOPi; /* attempt to convert to IV if possible. */ + SV *sv = TOPs; + IV iv; /* XXX it's arguable that compiler casting to IV might be subtly different from modf (for numbers inside (IV_MIN,UV_MAX)) in which else preferring IV has introduced a subtle behaviour change bug. OTOH relying on floating point to be accurate is a bug. */ - if (!SvOK(TOPs)) + while (SvAMAGIC(sv)) { + SV *tsv = AMG_CALLun(sv,numer); + if (SvROK(tsv) && SvRV(tsv) == SvRV(sv)) { + SETi(PTR2IV(SvRV(sv))); + RETURN; + } + else + sv = tsv; + } + iv = SvIV(sv); /* attempt to convert to IV if possible. */ + + if (!SvOK(sv)) { SETu(0); - else if (SvIOK(TOPs)) { - if (SvIsUV(TOPs)) { - const UV uv = TOPu; - SETu(uv); - } else + } + else if (SvIOK(sv)) { + if (SvIsUV(sv)) + SETu(SvUV(sv)); + else SETi(iv); - } else { - const NV value = TOPn; + } + else if (SvROK(sv)) { + SETi(iv); + } + else { + const NV value = SvNV(sv); if (value >= 0.0) { if (value < (NV)UV_MAX + 0.5) { SETu(U_V(value)); |