[Python-Dev] gcc 4.2 exposes signed integer overflows

Tim Peters tim.peters at gmail.com
Mon Aug 28 04:32:52 CEST 2006


[Anthony Baxter]
> Regardless of whether we consider gcc's behaviour to be correct or not,

It is correct, but more to the point it's, umm, /there/ ;-)

> I do agree we need a fix for this in 2.5 final. That should also be backported to
> release24-maint for the 2.4.4 release, and maybe release23-maint, as Barry
> recently started talking about cutting a 2.3.6.
>
> Can I nominate Tim, with his terrifying knowledge of C compiler esoterica, as
> the person to pick the best fix?

It's a bitch.  Changing to

	if (y == -1 && x < 0 && (unsigned long)x == -(unsigned long)x)

is the obvious fix, but violates our "no warnings" policy:  the MS
compiler warns about applying unary minus to an unsigned operand -- it
"looks insane" to /their/ compiler writers ;-).  Elegant patch below
-- LOL.

Would be nice if someone verified it worked on a box where it matters.
 Would also be nice if people checked to see whether their compiler(s)
warn about something else now.

IIndex: Objects/intobject.c
===================================================================
--- Objects/intobject.c (revision 51618)
+++ Objects/intobject.c (working copy)
@@ -564,8 +564,14 @@
                                "integer division or modulo by zero");
                return DIVMOD_ERROR;
        }
-       /* (-sys.maxint-1)/-1 is the only overflow case. */
-       if (y == -1 && x < 0 && x == -x)
+       /* (-sys.maxint-1)/-1 is the only overflow case.  x is the most
+        * negative long iff x < 0 and, on a 2's-complement box, x == -x.
+        * However, -x is undefined (by C) if x /is/ the most negative long
+        * (it's a signed overflow case), and some compilers care.  So we cast
+        * x to unsigned long first.  However, then other compilers warn about
+        * applying unary minus to an unsigned operand.  Hence the weird "0-".
+        */
+       if (y == -1 && x < 0 && (unsigned long)x == 0-(unsigned long)x)
                return DIVMOD_OVERFLOW;
        xdivy = x / y;
        xmody = x - xdivy * y;


More information about the Python-Dev mailing list