This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Miscompilation of remainder expressions


On 16/01/07, Duncan Sands <baldrick@free.fr> wrote:
On Tuesday 16 January 2007 16:50, Andrew Haley wrote:
> Roberto Bagnara writes:
>  > Andrew Haley wrote:
>  > > Roberto Bagnara writes:
>  > >  >
>  > >  > Reading the thread "Autoconf manual's coverage of signed integer
>  > >  > overflow & portability" I was horrified to discover about GCC's
>  > >  > miscompilation of the remainder expression that causes INT_MIN % -1
>  > >  > to cause a SIGFPE on CPUs of the i386 family.  Are there plans to
>  > >  > fix this bug (which, to me, looks quite serious)?
>  > >
>  > > No, there aren't.  It would make more sense for you to wrap % in some
>  > > code that checks for this, rather than for us to slow down every division
>  > > for this one special case.
>  >
>  > With all due respect, I must say I am shocked.  I always thought
>  > (and taught) that we, Free Software people, value standard conformance
>  > and getting things right.
>
> This is a disgreement about interpretation of the langauge in the
> standard, which is:
>
> "The result of the / operator is the quotient from the division of the
> first operand by the second; the result of the % operator is the
> remainder. In both operations, if the value of the second operand is
> zero, the behavior is undefined. When integers are divided, the result
> of the / operator is the algebraic quotient with any fractional part
> discarded.87) If the quotient a/b is representable, the expression
> (a/b)*b + a%b shall equal a."
>
> If the quotient a/b is *not* representable, is the behaviour of %
> well-defined or not?  It doesn't say.

In ada/exp_ch4.adb you will find:

         --  Deal with annoying case of largest negative number remainder
         --  minus one. Gigi does not handle this case correctly, because
         --  it generates a divide instruction which may trap in this case.

         --  In fact the check is quite easy, if the right operand is -1,
         --  then the mod value is always 0, and we can just ignore the
         --  left operand completely in this case.

Ada semantics require INT_MIN rem -1 to be zero.

FWIW,

manu@localhost:~$ gcc --version
gcc (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)

manu@localhost:~$ cat test.c
#include <limits.h>
#include <stdio.h>

int main(void) {
   int z = INT_MIN % -1;
   printf("%d %% %d -> %d\n", INT_MIN, -1, z);
   return 0;
}

manu@localhost:~$ gcc -Wall -Wextra test.c -o test
manu@localhost:~$ ./test
-2147483648 % -1 -> 0

manu@localhost:~$ cat test.c
#include <limits.h>
#include <stdio.h>

int modulo(int dividend, int divisor)
{
   return dividend % divisor;
}
int main(void) {
   int z = modulo(INT_MIN, -1);
   printf("%d %% %d -> %d\n", INT_MIN, -1, z);
   return 0;
}
manu@localhost:~$ gcc  -Wall -Wextra test.c -o test
manu@localhost:~$ ./test
Floating point exception
manu@localhost:~$ gcc -O2 -Wall -Wextra test.c -o test
manu@localhost:~$ ./test
Floating point exception
manu@localhost:~$ gcc -O3 -Wall -Wextra test.c -o test
manu@localhost:~$ ./test
-2147483648 % -1 -> 0

I don't know whether results are different in mainline.

Cheers,

Manuel.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]