Skip Menu |
Report information
Id: 77456
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: ntyni [at] debian.org
Cc:
AdminCc:

Operating System: Linux
PatchStatus: (no value)
Severity: low
Type:
Perl Version: 5.13.4
Fixed In: 5.13.8



Subject: unexpected NV conversion in numeric comparison + overloading
Date: Thu, 26 Aug 2010 22:36:29 +0300
To: perlbug [...] perl.org
From: Niko <ntyni [...] cc.helsinki.fi>
Download (untitled) / with headers
text/plain 4.5k
This is a bug report for perl from Niko Tyni <ntyni@debian.org>, generated with the help of perlbug 1.39 running under perl 5.13.4. ----------------------------------------------------------------- As seen in [rt.cpan.org #59478] and http://bugs.debian.org/593764 overloading numeric conversion and then doing numeric comparison triggers an unexpected IV -> NV conversion behind the scenes. Test 1 of the following script fails with 64-bit integers and 64-bit doubles because precision is lost in the conversion process. While I can see that this may not be a bug at all, consider that it was originally seen with the Moose test suite where an object was overloaded to numify as its refaddr() value. Having two objects compare as equivalent is certainly surprising behaviour here, particularly as it only showed up on the ia64 ("Itanium") architecture where refaddr() returns big integers instead of small ones. Anyway, feel free to close this ticket if it's all working as it should. #!perl package Foo; my $i = 1 << 53; use overload '0+' => sub { $i++ }, fallback => 1; 1; package main; print "1..2\n"; my $f1 = bless {}, 'Foo'; my $f2 = bless {}, 'Foo'; print ((($f1 == $f2) ? "not " : "") . "ok 1 - equivalence first\n"); print (((0+$f1 == 0+$f2) ? "not " : "") . "ok 2 - numification first\n"); __END__ ----------------------------------------------------------------- --- Flags: category=core severity=low --- Site configuration information for perl 5.13.4: Configured by niko at Thu Aug 26 19:13:41 EEST 2010. Summary of my perl5 (revision 5 version 13 subversion 4) configuration: Derived from: 1a0a2ba99e0c0ff795f145aaf54fcf0c4a8f7478 Platform: osname=linux, osvers=2.6.32-5-amd64, archname=x86_64-linux-gnu-thread-multi uname='linux madeleine 2.6.32-5-amd64 #1 smp thu aug 12 13:01:50 utc 2010 x86_64 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=x86_64-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.13 -Darchlib=/usr/lib/perl/5.13 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.13.4 -Dsitearch=/usr/local/lib/perl/5.13.4 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=both -Doptimize=-O0 -Dusedevel -Uuseshrplib -des' hint=recommended, useposix=true, d_sigaction=define useithreads=define, usemultiplicity=define useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef use64bitint=define, use64bitall=define, uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O0 -g', cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include' ccversion='', gccversion='4.4.5 20100816 (prerelease)', gccosandvers='' intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16 ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=8, prototype=define Linker and Libraries: ld='cc', ldflags =' -fstack-protector -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /lib64 /usr/lib64 libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc -lgdbm_compat perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc libc=/lib/libc-2.11.2.so, so=so, useshrplib=false, libperl=libperl.a gnulibc_version='2.11.2' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -O0 -g -L/usr/local/lib -fstack-protector' Locally applied patches: --- @INC for perl 5.13.4: lib /usr/local/lib/perl/5.13.4 /usr/local/share/perl/5.13.4 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.13 /usr/share/perl/5.13 /usr/local/share/perl /usr/share/perl5 . --- Environment for perl 5.13.4: HOME=/home/niko LANG=en_US.UTF-8 LANGUAGE (unset) LC_CTYPE=fi_FI.UTF-8 LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/niko/bin:/home/niko/bin:/home/niko/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin:/sbin:/usr/sbin PERL_BADLANG (unset) SHELL=/bin/zsh
Subject: Re: [perl #77456] unexpected NV conversion in numeric comparison + overloading
Date: Fri, 27 Aug 2010 10:27:44 +0100
To: perl5-porters [...] perl.org
From: Zefram <zefram [...] fysh.org>
Download (untitled) / with headers
text/plain 268b
Niko Tyni wrote: Show quoted text
>As seen in [rt.cpan.org #59478] and http://bugs.debian.org/593764 >overloading numeric conversion and then doing numeric comparison triggers >an unexpected IV -> NV conversion behind the scenes.
This also strongly resembles [perl #46011]. -zefram
Subject: Re: [perl #77456] unexpected NV conversion in numeric comparison + overloading
Date: Wed, 15 Dec 2010 19:47:30 +0000
To: perl5-porters [...] perl.org
From: Dave Mitchell <davem [...] iabyn.com>
Download (untitled) / with headers
text/plain 1.8k
On Thu, Aug 26, 2010 at 12:37:03PM -0700, Niko Tyni wrote: Show quoted text
> As seen in [rt.cpan.org #59478] and http://bugs.debian.org/593764 > overloading numeric conversion and then doing numeric comparison triggers > an unexpected IV -> NV conversion behind the scenes. > > Test 1 of the following script fails with 64-bit integers and 64-bit > doubles because precision is lost in the conversion process. > > While I can see that this may not be a bug at all, consider that > it was originally seen with the Moose test suite where an object was > overloaded to numify as its refaddr() value. Having two objects compare > as equivalent is certainly surprising behaviour here, particularly as > it only showed up on the ia64 ("Itanium") architecture where refaddr() > returns big integers instead of small ones. > > Anyway, feel free to close this ticket if it's all working as it should. > > #!perl > > package Foo; > > my $i = 1 << 53; > use overload '0+' => sub { $i++ }, > fallback => 1; > 1; > > package main; > > print "1..2\n"; > my $f1 = bless {}, 'Foo'; > my $f2 = bless {}, 'Foo'; > > print ((($f1 == $f2) ? "not " : "") . "ok 1 - equivalence first\n"); > print (((0+$f1 == 0+$f2) ? "not " : "") . "ok 2 - numification first\n");
Now fixed with this commit: commit a42d02426c51c2ef1bdefac84284a828de703cda Author: David Mitchell <davem@iabyn.com> AuthorDate: Wed Dec 15 19:38:17 2010 +0000 Commit: David Mitchell <davem@iabyn.com> CommitDate: Wed Dec 15 19:41:46 2010 +0000 don't upgrade overload IV return values to NV (if we can avoid it). Fix for RT #77456. Basically it extends the usage of the AMGf_numeric flag to the remaining overloadable numeric ops that behave differently with IV and NV. Affected files ... M lib/overload64.t M pp.c M pp_hot.c -- Modern art: "That's easy, I could have done that!" "Ah, but you didn't!"


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org