]> granicus.if.org Git - python/commitdiff
i_divmod(): As discussed on Python-Dev, changed the overflow
authorTim Peters <tim.peters@gmail.com>
Tue, 5 Sep 2006 01:47:53 +0000 (01:47 +0000)
committerTim Peters <tim.peters@gmail.com>
Tue, 5 Sep 2006 01:47:53 +0000 (01:47 +0000)
checking to live happily with recent gcc optimizations that
assume signed integer arithmetic never overflows.

Misc/NEWS
Objects/intobject.c

index 84f0cf660bf0cf3a60c27899f5a07a4c8521bc6a..3b9dba0f0023b7e2a4e64c1028dc177094ba39c3 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.5?
 Core and builtins
 -----------------
 
+- Overflow checking code in integer division ran afoul of new gcc
+  optimizations.  Changed to be more standard-conforming.
+
 - Patch #1541585: fix buffer overrun when performing repr() on
   a unicode string in a build with wide unicode (UCS-4) support.
 
@@ -127,7 +130,7 @@ Library
 - The __repr__ method of a NULL ctypes.py_object() no longer raises
   an exception.
 
-- uuid.UUID now has a bytes_le attribute. This returns the UUID in 
+- uuid.UUID now has a bytes_le attribute. This returns the UUID in
   little-endian byte order for Windows. In addition, uuid.py gained some
   workarounds for clocks with low resolution, to stop the code yielding
   duplicate UUIDs.
@@ -286,7 +289,7 @@ Library
 - Bug #1002398: The documentation for os.path.sameopenfile now correctly
   refers to file descriptors, not file objects.
 
-- The renaming of the xml package to xmlcore, and the import hackery done 
+- The renaming of the xml package to xmlcore, and the import hackery done
   to make it appear at both names, has been removed.  Bug #1511497,
   #1513611, and probably others.
 
index c7137df40ba83df80c063a22b6a305c65d62a63d..b94e3e988707031b81b16de577d92346c2315ec8 100644 (file)
@@ -564,8 +564,14 @@ i_divmod(register long x, register long y,
                                "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;