Skip to content

Commit e63dab5

Browse files
committed
Merge rev 51711 from the 2.5 branch.
i_divmod(): As discussed on Python-Dev, changed the overflow checking to live happily with recent gcc optimizations that assume signed integer arithmetic never overflows.
1 parent ba8522a commit e63dab5

2 files changed

Lines changed: 11 additions & 2 deletions

File tree

‎Misc/NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.4.4c1?
1212
Core and builtins
1313
-----------------
1414

15+
- Overflow checking code in integer division ran afoul of new gcc
16+
optimizations. Changed to be more standard-conforming.
17+
1518
- Patch #1541585: fix buffer overrun when performing repr() on
1619
a unicode string in a build with wide unicode (UCS-4) support.
1720

‎Objects/intobject.c‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,8 +478,14 @@ i_divmod(register long x, register long y,
478478
"integer division or modulo by zero");
479479
return DIVMOD_ERROR;
480480
}
481-
/* (-sys.maxint-1)/-1 is the only overflow case. */
482-
if (y == -1 && x < 0 && x == -x)
481+
/* (-sys.maxint-1)/-1 is the only overflow case. x is the most
482+
* negative long iff x < 0 and, on a 2's-complement box, x == -x.
483+
* However, -x is undefined (by C) if x /is/ the most negative long
484+
* (it's a signed overflow case), and some compilers care. So we cast
485+
* x to unsigned long first. However, then other compilers warn about
486+
* applying unary minus to an unsigned operand. Hence the weird "0-".
487+
*/
488+
if (y == -1 && x < 0 && (unsigned long)x == 0-(unsigned long)x)
483489
return DIVMOD_OVERFLOW;
484490
xdivy = x / y;
485491
xmody = x - xdivy * y;

0 commit comments

Comments
 (0)