Alastair Reid <[EMAIL PROTECTED]> writes:

> A slightly simpler example is:
> 
>   Prelude> (minBound :: Int) `primDivInt` (-1)
> 
>   Unexpected signal
> 
> The problem is probably coming from trying to calculate one of the following.
> 
>   minBound % -1
>   minBound / -1

I looked into this some more, and it seems to be a "feature" of the X86.

Consider the following program:

-------------------- cut here --------------------
#include <stdio.h>
#include <limits.h>

int main(int argc, char **argv) {
  int i = INT_MIN;
  int j = -1;

  if (i/j == i) {
    printf("Expected\n");
  } else {
    printf("Unexpected\n");
  }
}
-------------------- cut here --------------------

If I compile and run it under Linux (using libc5 and libc6; kernel
versions 2.0.27 or 2.0.29; 80486, Pentium Pro, or Pentium II) I get:

> gcc -o div div.c ; ./div
Floating exception

If I compile it with -O2 (so that gcc tries to do constant folding) I
get:

> gcc -o div -O2 div.c
gcc: Internal compiler error: program cc1 got fatal signal 6

It crashes the compiler!

If I compile it with VC 4.2 under Windows NT and run it, I get a
little dialog box that says "The exception Integer overflow.
(0xc0000095) occurred in the application at location 0x0040101b."

I'm guessing the right solution would be to change primDivInt (and the
other division-related primitives) to have something like:

    if (y == 0
#ifdef CANNOT_DIV_INT_MIN_MINUS1
        || (x == INT_MIN && y == -1)
#endif
        )
        cantReduce();

where the CANNOT_DIV_INT_MIN_MINUS1 would be from a configure test.

Carl Witty
[EMAIL PROTECTED]

Reply via email to