ZeroDivide bug in float printing

Derek Zhou <[email protected]>
Newsgroups gmane.comp.lang.smalltalk.gnu.general
Message-ID <[email protected]>
list,

There were discussion on this list about this bug in the debian package:

st> 0.1
Object: 1 error: The program attempted to divide a number by zero
ZeroDivide(Exception)>>signal (ExcHandling.st:254)
SmallInteger(Number)>>zeroDivide (SysExcept.st:1426)
Fraction>>setNumerator:setDenominator: (Fraction.st:485)
Fraction class>>numerator:denominator: (Fraction.st:66)
Fraction>>- (Fraction.st:151)
...
st> 4294967296 * 4294967296
0

Last night I tracked it down. It only happens with:

 * 64 bit arch
 * gcc 4.9.x

The reason is smalltalk has to detect integer multiplication overflow
reliably; and there were 3 ways in the code:

 1. use __builtin_mul_overflow
 2, see if the result is too big or too small
 3, basically a * b / b == a ? OK : OVERFLOW

gcc 5+ and clang use 1. 32 bit arch use 2. they all works. However, on
gcc 4.9 and 64 bit it has to fall back to 3 which does not work. The
reason is gcc is being overly smart and optimize it away. gcc does
provide a switch "-fwrapv" to disable this optimization, but I am not
sure what other thing it may cause and we dont want to get caught in the
compiler shenanigan again in other compilers or other platform.

I propose to change 3 into a more conservative and slower test
such as:

(MAX_ST_INT / abs(b)) < abs(a) ? OVERFLOW : OK

I will follow up with a patch

Derek
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.