Closed p5pRT closed 16 years ago
This perl is configured with 64-bit integers and 64-bit floats (1+52 bits of significand).
$ perl -lwe '{ package t0; sub mynum { 36028797018963971 } use overload "0+" => \&mynum; } print int(t0::mynum); print int(bless({}\, "t0"))' 36028797018963971 36028797018963968 $
36028797018963971 is 2^55+3. Its salient feature here is that it's a native integer that can't be exactly represented as a native float. When it's returned by the "0+" overload function\, it's being unnecessarily and lossily coerced to float. This coercion doesn't happen if the return value of t0::mynum() goes directly into int() without going via the overloading system.
On Oct 02 2007\, Zefram wrote:
This perl is configured with 64-bit integers and 64-bit floats (1+52 bits of significand).
$ perl -lwe '{ package t0; sub mynum { 36028797018963971 } use overload "0+" => \&mynum; } print int(t0::mynum); print int(bless({}\, "t0"))' 36028797018963971 36028797018963968 $
36028797018963971 is 2^55+3. Its salient feature here is that it's a native integer that can't be exactly represented as a native float. When it's returned by the "0+" overload function\, it's being unnecessarily and lossily coerced to float. This coercion doesn't happen if the return value of t0::mynum() goes directly into int() without going via the overloading system.
The problem here is that the arg passed to int() is checked if IOK (integer) but because it's a reference\, it's not. So it is treated as a float (NV). And currently it actually calls mynum() twice for the second int() call. The attached patch fixes that and should fix your problem\, although I couldn't test it directly. I added tests for the call-twice problem\, but wasn't sure how to add one for the 64-bit int issue.
-- Rick Delaney rick@bort.ca
The RT System itself - Status changed from 'new' to 'open'
On 07/10/2007\, Rick Delaney \rick@​bort\.ca wrote:
The problem here is that the arg passed to int() is checked if IOK (integer) but because it's a reference\, it's not. So it is treated as a float (NV). And currently it actually calls mynum() twice for the second int() call. The attached patch fixes that and should fix your problem\, although I couldn't test it directly. I added tests for the call-twice problem\, but wasn't sure how to add one for the 64-bit int issue.
Thanks\, applied as change #32059\, and I confirmed that fixes the bug on 64-bit int perl.
@rgs - Status changed from 'open' to 'resolved'
Rick Delaney wrote:
The problem here is that the arg passed to int() is checked if IOK (integer) but because it's a reference\, it's not. So it is treated as a float (NV). And currently it actually calls mynum() twice for the second int() call. The attached patch fixes that and should fix your problem\, although I couldn't test it directly. I added tests for the call-twice problem\, but wasn't sure how to add one for the 64-bit int issue.
Rafael Garcia-Suarez wrote:
Thanks\, applied as change #32059\, and I confirmed that fixes the bug on 64-bit int perl.
This is the same bug as reported by me exactly 2 years ago: http://rt.perl.org/rt3/Ticket/Display.html?id=37363 Glad to see it's finally fixed.
Rafael\, would you please resolve bug 37363 (or whatever is appropriate in this case)? I don't have permission to do so. Thanks.
Rafael Garcia-Suarez via RT wrote:
According to our records\, your request regarding "overload "0+" doesn't handle integer results" has been resolved.
I looked up the patch that was posted to perl5-porters\, and it solves this issue only for int(). There's an equivalent bug still there for other operations:
$ perl -lwe '{ package t0; sub mynum { 36028797018963971 } use overload "0+" => \&mynum\, fallback => 1; } printf "%d\n"\, 0+t0::mynum; printf "%d\n"\, 0+bless({}\, "t0")'
It works OK for plain printf "%d"\, but not for addition. Also doesn't work for subtraction\, negation\, multiplication\, division\, remainder. Does work for bit shift and bitwise OR. Perhaps some code factoring is called for.
-zefram
On Oct 07 2007\, Zefram wrote:
I looked up the patch that was posted to perl5-porters\, and it solves this issue only for int(). There's an equivalent bug still there for other operations:
$ perl -lwe '{ package t0; sub mynum { 36028797018963971 } use overload "0+" => \&mynum\, fallback => 1; } printf "%d\n"\, 0+t0::mynum; printf "%d\n"\, 0+bless({}\, "t0")'
I wish you'd mentioned that before.
It works OK for plain printf "%d"\, but not for addition. Also doesn't work for subtraction\, negation\, multiplication\, division\, remainder. Does work for bit shift and bitwise OR. Perhaps some code factoring is called for.
Undoubtedly. In the meantime here is another patch to fix a segfault introduced by the first.
-- Rick Delaney rick@bort.ca
On 08/10/2007\, Rick Delaney \rick@​bort\.ca wrote:
Undoubtedly. In the meantime here is another patch to fix a segfault introduced by the first.
Thanks\, applied.
On 08/10/2007\, Rafael Garcia-Suarez \rgarciasuarez@​gmail\.com wrote:
On 08/10/2007\, Rick Delaney \rick@​bort\.ca wrote:
Undoubtedly. In the meantime here is another patch to fix a segfault introduced by the first.
Thanks\, applied.
From the smoke tests\, it seems that test 531 fails for builds with -Duse64bitall. I can't test with this configuration.
On Mon\, 8 Oct 2007 14:01:02 +0200\, "Rafael Garcia-Suarez" \rgarciasuarez@​gmail\.com wrote:
On 08/10/2007\, Rafael Garcia-Suarez \rgarciasuarez@​gmail\.com wrote:
On 08/10/2007\, Rick Delaney \rick@​bort\.ca wrote:
Undoubtedly. In the meantime here is another patch to fix a segfault introduced by the first.
Thanks\, applied.
From the smoke tests\, it seems that test 531 fails for builds with
Smoke [5.10.0] 32059 FAIL(F) hp-ux B.11.23/64 gcc (ia64/2 cpu) http://www.test-smoke.org/reports/50698
-Duse64bitall. I can't test with this configuration.
I did two manual runs with -Duse64bitall on 32068
Linux 2.6.18.8-0.5 x86_64 Xeon(R) CPU E5320 @ 1.86GHz/1596(4) x86_64 3951 Mb
All tests successful\, 70 tests and 758 subtests skipped. Files=1461\, Tests=185010\, 512 wallclock secs (258.50 cusr + 35.60 csys = 294.10 CPU)
HP-UX 11.23/64 U rx1620/64 Itanium 2/1600(2) ia64 2037 Mb
Failed Test Stat Wstat Total Fail List of Failed
../lib/overload.t 2 512 536 2 531 536 (2 subtests UNEXPECTEDLY SUCCEEDED)\, 74 tests and 788 subtests skipped. Failed 1/1460 test scripts. 2/184816 subtests failed. Files=1460\, Tests=184816\, 780 wallclock secs (454.83 cusr + 98.65 csys = 553.48 CPU) Failed 1/1460 test programs. 2/184816 subtests failed.
x1:/pro/3gl/CPAN/perl-current/t 112 > ./perl -I../lib ../lib/overload.t 1..536 ok 1 ok 2 : : ok 527 ok 528 ok 529 - numifies to integer ok 530 - int() numifies only once not ok 531 - numifies to self # Failed test 'numifies to self' # at ../lib/overload.t line 1397. # got: '6917529027645582112' # expected: '6.91752902764558e+18' ok 532 - int() numifies once when returning self ok 533 - numifies to numification of other object ok 534 - int() numifies once when returning other object ok 535 - returned object numifies too not ok 536 - numifies to usual reference value # Failed test 'numifies to usual reference value' # at ../lib/overload.t line 1406. # got: '6917529027645582112' # expected: '6.91752902764558e+18' # Looks like you failed 2 tests of 536.
On a side note\, I don't like messages like this:
../lib/Module/Build/t/ppm........................................ok 2/12Invalid header block at offset unknown at ../lib/Module/Build/t/ppm.t line 122 Couldn't read chunk at offset unknown at ../lib/Module/Build/t/ppm.t line 122 Read error on tarfile (missing data) 'blib/html/bin/hello.html' at offset unknown at ../lib/Module/Build/t/ppm.t line 122 ../lib/Module/Build/t/ppm........................................ok 10/12Invalid header block at offset unknown at ../lib/Module/Build/t/ppm.t line 174 Couldn't read chunk at offset unknown at ../lib/Module/Build/t/ppm.t line 174 Read error on tarfile (missing data) 'blib/html/bin/hello.html' at offset unknown at ../lib/Module/Build/t/ppm.t line 174
Can't those be silenced?
-- H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/) using & porting perl 5.6.2\, 5.8.x\, 5.9.x on HP-UX 10.20\, 11.00\, 11.11\, & 11.23\, SuSE 10.0 & 10.2\, AIX 4.3 & 5.2\, and Cygwin. http://qa.perl.org http://mirrors.develooper.com/hpux/ http://www.test-smoke.org http://www.goldmark.org/jeff/stupid-disclaimers/
On 08 Oct 2007\, at 14:18\, H.Merijn Brand wrote:
../lib/Module/Build/t/ppm........................................ok
2/12Invalid header block at offset unknown at ../lib/Module/Build/t/ ppm.t line 122 Couldn't read chunk at offset unknown at ../lib/Module/Build/t/ ppm.t line 122 Read error on tarfile (missing data) 'blib/html/bin/hello.html' at
offset unknown at ../lib/Module/Build/t/ppm.t line 122 ../lib/Module/Build/t/ppm........................................ok
10/12Invalid header block at offset unknown at ../lib/Module/Build/ t/ppm.t line 174 Couldn't read chunk at offset unknown at ../lib/Module/Build/t/ ppm.t line 174 Read error on tarfile (missing data) 'blib/html/bin/hello.html' at
offset unknown at ../lib/Module/Build/t/ppm.t line 174Can't those be silenced?
They can be by setting C\<$Archive::Tar::WARN = 0>\, however you probably don't want to as these are pointing to a real issue; an .html file is being used a tar file\, which is not quite working obviously.
This may point to a more serious issue underneath.
--
Jos Boumans
How do I prove I'm not crazy to people who are?
Zefram wrote:
It works OK for plain printf "%d"\, but not for addition. Also doesn't work for subtraction\, negation\, multiplication\, division\, remainder. Does work for bit shift and bitwise OR. Perhaps some code factoring is called for.
The attached patch adds tests for these to lib/overload.t. The tests are skipped if not using 64-bit ints. The following tests (which fail for me) are set as TODO: 0+ (addition) subtraction multiplication division modulo (%) exponentiation (**) abs()
The following tests (which fail for me) are set as TODO: 0+ (addition) subtraction multiplication division modulo (%) exponentiation (**) abs()
Ticket should be reopened because the above still need fixing.
On Oct 08 2007\, H.Merijn Brand wrote:
I did two manual runs with -Duse64bitall on 32068
Linux 2.6.18.8-0.5 x86_64 Xeon(R) CPU E5320 @ 1.86GHz/1596(4) x86_64 3951 Mb
All tests successful\, 70 tests and 758 subtests skipped. Files=1461\, Tests=185010\, 512 wallclock secs (258.50 cusr + 35.60 csys = 294.10 CPU)
HP-UX 11.23/64 U rx1620/64 Itanium 2/1600(2) ia64 2037 Mb ... not ok 531 - numifies to self # Failed test 'numifies to self' # at ../lib/overload.t line 1397. # got: '6917529027645582112' # expected: '6.91752902764558e+18'
The expected value is just
my $aref = []; my $num_val = 0 + $aref;
So it means that a regular reference in numeric context is returning an NV or that pp_add is not doing integer math when it should here. I would say that either one is a separate bug.
I'm pretty sure changing the line to
my $num_val = int($aref);
will make the tests pass without changing the semantic of the test too much. But we could probably use some TODO tests to ensure that references in numeric context are always returning IVs. Or is there a platform with pointers bigger than IVs?
-- Rick Delaney rick@bort.ca
On 08/10/2007\, Rick Delaney \rick@​bort\.ca wrote:
I'm pretty sure changing the line to
my $num\_val = int\($aref\);
will make the tests pass without changing the semantic of the test too
Thanks\, tweaked as #32071.
much. But we could probably use some TODO tests to ensure that references in numeric context are always returning IVs. Or is there a platform with pointers bigger than IVs?
I think IVs are guaranteed to be able to hold pointers.
Zefram wrote:
It works OK for plain printf "%d"\, but not for addition. Also doesn't work for subtraction\, negation\, multiplication\, division\, remainder. Does work for bit shift and bitwise OR. Perhaps some code factoring is called for.
Jerry D. Hedden wrote:
The attached patch adds tests for these to lib/overload.t. The tests are skipped if not using 64-bit ints. The following tests (which fail for me) are set as TODO: 0+ (addition) subtraction multiplication division modulo (%) exponentiation (**) abs()
Programming by example\, the attached patch fixes the above problem for abs() overloading. I added more tests as well. (This supercedes my previous patch with lib/overload.t tests.)
Zefram wrote:
It works OK for plain printf "%d"\, but not for addition. Also doesn't work for subtraction\, negation\, multiplication\, division\, remainder. Does work for bit shift and bitwise OR. Perhaps some code factoring is called for.
Jerry D. Hedden wrote:
The attached patch adds tests for these to lib/overload.t. The tests are skipped if not using 64-bit ints. The following tests (which fail for me) are set as TODO: 0+ (addition) subtraction multiplication division modulo (%) exponentiation (**) abs()
The attached patch (which supercedes my previous patches on the matter) fixes the above problem for 'abs' and 'neg' overloading. I added more tests as well.
The patch can be check using the following:
./perl -Ilib -lwe '{ package t0; sub mynum { -36028797018963971 } use overload "0+" => \&mynum\, fallback => 1; } printf "%d\n"\, abs(t0::mynum); printf "%d\n"\, abs(bless({}\, "t0"))'
./perl -Ilib -lwe '{ package t0; sub mynum { -36028797018963971 } use overload "0+" => \&mynum\, fallback => 1; } printf "%d\n"\, -&t0::mynum; printf "%d\n"\, -bless({}\, "t0")'
I'm really on a roll here. I think I know how to fix all of this stuff\, but there are dozens of fuctions to tackle. Please disregard this patch (and the previous ones\, too). I'll work all this out and submit one big patch that does it all. Sorry for the noise.
Zefram wrote:
It works OK for plain printf "%d"\, but not for addition. Also doesn't work for subtraction\, negation\, multiplication\, division\, remainder. Does work for bit shift and bitwise OR. Perhaps some code factoring is called for.
Jerry D. Hedden wrote:
The attached patch adds tests for these to lib/overload.t. The tests are skipped if not using 64-bit ints. The following tests (which fail for me) are set as TODO: 0+ (addition) subtraction multiplication division modulo (%) exponentiation (**) abs()
The attached patch (which supercedes my previous patches on the matter) fixes the above problem for 'abs' and 'neg' overloading. I added more tests as well.
The patch can be check using the following:
./perl -Ilib -lwe '{ package t0; sub mynum { -36028797018963971 } use overload "0+" => \&mynum\, fallback => 1; } printf "%d\n"\, abs(t0::mynum); printf "%d\n"\, abs(bless({}\, "t0"))'
./perl -Ilib -lwe '{ package t0; sub mynum { -36028797018963971 } use overload "0+" => \&mynum\, fallback => 1; } printf "%d\n"\, -&t0::mynum; printf "%d\n"\, -bless({}\, "t0")'
On Oct 08 2007\, Jerry D. Hedden wrote:
I'm really on a roll here. I think I know how to fix all of this stuff\, but there are dozens of fuctions to tackle. Please disregard this patch (and the previous ones\, too). I'll work all this out and submit one big patch that does it all. Sorry for the noise.
Thanks for taking this on. I was going to do it but I'm pretty slow with stuff that doesn't affect me directly.
Please refactor the common stuff into a macro or function\, though. And we could use tests for these ops on plain ol' references\, too\, since they are also (I think) returning floats for 64bit when they should return ints. I'm pretty sure the tests will be welcome before the code patch too. If it's not too much trouble. :-)
P.S. I think PTR2IV should be PTR2UV for the reference case.
-- Rick Delaney rick@bort.ca
On Mon\, 8 Oct 2007 10:18:05 -0400\, Rick Delaney \rick@​bort\.ca wrote:
On Oct 08 2007\, H.Merijn Brand wrote:
I did two manual runs with -Duse64bitall on 32068
Linux 2.6.18.8-0.5 x86_64 Xeon(R) CPU E5320 @ 1.86GHz/1596(4) x86_64 3951 Mb
All tests successful\, 70 tests and 758 subtests skipped. Files=1461\, Tests=185010\, 512 wallclock secs (258.50 cusr + 35.60 csys = 294.10 CPU)
HP-UX 11.23/64 U rx1620/64 Itanium 2/1600(2) ia64 2037 Mb ... not ok 531 - numifies to self # Failed test 'numifies to self' # at ../lib/overload.t line 1397. # got: '6917529027645582112' # expected: '6.91752902764558e+18'
The expected value is just
my $aref = \[\]; my $num\_val = 0 \+ $aref;
So it means that a regular reference in numeric context is returning an NV or that pp_add is not doing integer math when it should here. I would say that either one is a separate bug.
I'm pretty sure changing the line to
my $num\_val = int\($aref\);
will make the tests pass without changing the semantic of the test too much. But we could probably use some TODO tests to ensure that references in numeric context are always returning IVs. Or is there a platform with pointers bigger than IVs?
I don't think Configure allows that currently on the current supported systems
-- H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/) using & porting perl 5.6.2\, 5.8.x\, 5.9.x on HP-UX 10.20\, 11.00\, 11.11\, & 11.23\, SuSE 10.0 & 10.2\, AIX 4.3 & 5.2\, and Cygwin. http://qa.perl.org http://mirrors.develooper.com/hpux/ http://www.test-smoke.org http://www.goldmark.org/jeff/stupid-disclaimers/
Migrated from rt.perl.org#46011 (status was 'resolved')
Searchable as RT46011$