From: Yitzchak Scott-Thoennes Date: Mon, 13 Feb 2006 01:39:25 +0000 (-0800) Subject: Re: [perl #38485] use integer; 0x80000000/-1; # coredump X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a0cec76945276a0895c829a391529265d9b76bc0;p=p5sagit%2Fp5-mst-13.2.git Re: [perl #38485] use integer; 0x80000000/-1; # coredump Message-ID: <20060213093925.GA3476@efn.org> p4raw-id: //depot/perl@27205 --- diff --git a/lib/integer.t b/lib/integer.t index 5c353b3..c1bb4d0 100644 --- a/lib/integer.t +++ b/lib/integer.t @@ -7,7 +7,7 @@ BEGIN { use integer; -use Test::More tests => 12; +use Test::More tests => 15; use Config; my $x = 4.5; @@ -55,10 +55,15 @@ is(~0, -1, "signed instead of unsigned"); # [perl #38485] use integer; 0x80000000/-1; SKIP: { my $ivsize = $Config{ivsize}; - skip "ivsize == $ivsize", 2 unless $ivsize == 4 || $ivsize == 8; + skip "ivsize == $ivsize", 4 unless $ivsize == 4 || $ivsize == 8; my $iv_min = $ivsize == 4 ? -2147483648 : -9223372036854775808; my $biff; eval { $biff = $iv_min / -1 }; - like($@, qr/Integer overflow in division/, "Caught IV_MIN / -1"); + is($@, '', 'IV_MIN / -1 succeeds'); + is($biff, -$iv_min, 'IV_MIN / -1 == -IV_MIN'); + + eval { $biff = $iv_min % -1 }; + is($@, '', 'IV_MIN % -1 succeeds'); + is($biff, 0, 'IV_MIN % -1 == 0'); } diff --git a/pp.c b/pp.c index 4080c45..f9f9e7b 100644 --- a/pp.c +++ b/pp.c @@ -2433,9 +2433,12 @@ PP(pp_i_divide) if (value == 0) DIE(aTHX_ "Illegal division by zero"); num = POPi; - if (num == IV_MIN && value == -1) - DIE(aTHX_ "Integer overflow in division"); - value = num / value; + + /* avoid FPE_INTOVF on some platforms when num is IV_MIN */ + if (value == -1) + value = - num; + else + value = num / value; PUSHi( value ); RETURN; } @@ -2450,7 +2453,11 @@ PP(pp_i_modulo_0) dPOPTOPiirl; if (!right) DIE(aTHX_ "Illegal modulus zero"); - SETi( left % right ); + /* avoid FPE_INTOVF on some platforms when left is IV_MIN */ + if (right == -1) + SETi( 0 ); + else + SETi( left % right ); RETURN; } } @@ -2467,7 +2474,11 @@ PP(pp_i_modulo_1) dPOPTOPiirl; if (!right) DIE(aTHX_ "Illegal modulus zero"); - SETi( left % PERL_ABS(right) ); + /* avoid FPE_INTOVF on some platforms when left is IV_MIN */ + if (right == -1) + SETi( 0 ); + else + SETi( left % PERL_ABS(right) ); RETURN; } } @@ -2508,7 +2519,11 @@ PP(pp_i_modulo) } } #endif - SETi( left % right ); + /* avoid FPE_INTOVF on some platforms when left is IV_MIN */ + if (right == -1) + SETi( 0 ); + else + SETi( left % right ); RETURN; } }