Skip to content

Commit 98041d7

Browse files
committed
Fix integer negation and absolute value to not rely
on undefined behaviour of the C compiler anymore.
1 parent e346a73 commit 98041d7

3 files changed

Lines changed: 7 additions & 4 deletions

File tree

‎Lib/test/test_builtin.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ def test_abs(self):
101101
self.assertEqual(abs(0), 0)
102102
self.assertEqual(abs(1234), 1234)
103103
self.assertEqual(abs(-1234), 1234)
104+
self.assertTrue(abs(-sys.maxint-1) > 0)
104105
# float
105106
self.assertEqual(abs(0.0), 0.0)
106107
self.assertEqual(abs(3.14), 3.14)

‎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+
- Integer negation and absolute value were fixed to not rely
16+
on undefined behaviour of the C compiler anymore.
17+
1518
- Patch #1567691: super() and new.instancemethod() now don't accept
1619
keyword arguments any more (previously they accepted them, but didn't
1720
use them).

‎Objects/intobject.c‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -674,10 +674,9 @@ int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
674674
static PyObject *
675675
int_neg(PyIntObject *v)
676676
{
677-
register long a, x;
677+
register long a;
678678
a = v->ob_ival;
679-
x = -a;
680-
if (a < 0 && x < 0) {
679+
if (a < 0 && (unsigned long)a == 0-(unsigned long)a) {
681680
PyObject *o = PyLong_FromLong(a);
682681
if (o != NULL) {
683682
PyObject *result = PyNumber_Negative(o);
@@ -686,7 +685,7 @@ int_neg(PyIntObject *v)
686685
}
687686
return NULL;
688687
}
689-
return PyInt_FromLong(x);
688+
return PyInt_FromLong(-a);
690689
}
691690

692691
static PyObject *

0 commit comments

Comments
 (0)