]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-111178: Fix function signatures in longobject.c (#124895)
authorVictor Stinner <vstinner@python.org>
Wed, 2 Oct 2024 15:41:19 +0000 (17:41 +0200)
committerGitHub <noreply@github.com>
Wed, 2 Oct 2024 15:41:19 +0000 (17:41 +0200)
* Add _PyLong_CAST() macro.
* Move forward declarations to the top of longobject.c.
* Change long_add(), long_sub(), long_mul(), long_neg(),
  long_lshift(), long_abs() to take PyLongObject* and return
  PyLongObject*. Avoid CHECK_BINOP() test.
* Add long_add_method(), long_sub_method(), long_mul_method(),
  long_neg_method(), long_lshift_method(), and long_abs_method()
  which take PyObject* and return PyObject*. Implement CHECK_BINOP()
  test.
* Add long_lshift_int64() function.
* _PyLong_DivmodNear() calls long_lshift_int64(obj, 1) instead of
  long_lshift_obj(obj, one).

Include/cpython/longobject.h
Objects/longobject.c

index b239f7c557e016e8011ce1a91f205cc582523e18..c1214d5e3714ead44bda318fc5d9031e78993622 100644 (file)
@@ -2,6 +2,9 @@
 #  error "this header file must not be included directly"
 #endif
 
+#define _PyLong_CAST(op) \
+    (assert(PyLong_Check(op)), _Py_CAST(PyLongObject*, (op)))
+
 PyAPI_FUNC(PyObject*) PyLong_FromUnicodeObject(PyObject *u, int base);
 
 #define Py_ASNATIVEBYTES_DEFAULTS -1
index 9beb5884a6932b07f9afe1b31b0c342dcd6d5f20..6ca8d449bcf4a26605f645ef463b11cdf8d0ae5c 100644 (file)
@@ -31,6 +31,13 @@ class int "PyObject *" "&PyLong_Type"
 /* If defined, use algorithms from the _pylong.py module */
 #define WITH_PYLONG_MODULE 1
 
+// Forward declarations
+static PyLongObject* long_neg(PyLongObject *v);
+static PyLongObject *x_divrem(PyLongObject *, PyLongObject *, PyLongObject **);
+static PyObject* long_long(PyObject *v);
+static PyObject* long_lshift_int64(PyLongObject *a, int64_t shiftby);
+
+
 static inline void
 _Py_DECREF_INT(PyLongObject *op)
 {
@@ -266,17 +273,17 @@ _PyLong_FromLarge(stwodigits ival)
 }
 
 /* Create a new int object from a C word-sized int */
-static inline PyObject *
+static inline PyLongObject *
 _PyLong_FromSTwoDigits(stwodigits x)
 {
     if (IS_SMALL_INT(x)) {
-        return get_small_int((sdigit)x);
+        return (PyLongObject*)get_small_int((sdigit)x);
     }
     assert(x != 0);
     if (is_medium_int(x)) {
-        return _PyLong_FromMedium((sdigit)x);
+        return (PyLongObject*)_PyLong_FromMedium((sdigit)x);
     }
-    return _PyLong_FromLarge(x);
+    return (PyLongObject*)_PyLong_FromLarge(x);
 }
 
 /* If a freshly-allocated int is already shared, it must
@@ -292,7 +299,7 @@ _PyLong_Negate(PyLongObject **x_p)
         return;
     }
 
-    *x_p = (PyLongObject *)_PyLong_FromSTwoDigits(-medium_value(x));
+    *x_p = _PyLong_FromSTwoDigits(-medium_value(x));
     Py_DECREF(x);
 }
 
@@ -2619,8 +2626,6 @@ long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int
     return 0;
 }
 
-static PyObject *long_neg(PyLongObject *v);
-
 #ifdef WITH_PYLONG_MODULE
 /* asymptotically faster str-to-long conversion for base 10, using _pylong.py */
 static int
@@ -3149,11 +3154,6 @@ PyLong_FromUnicodeObject(PyObject *u, int base)
     return NULL;
 }
 
-/* forward */
-static PyLongObject *x_divrem
-    (PyLongObject *, PyLongObject *, PyLongObject **);
-static PyObject *long_long(PyObject *v);
-
 /* Int division with remainder, top-level routine */
 
 static int
@@ -3746,11 +3746,12 @@ x_sub(PyLongObject *a, PyLongObject *b)
     return maybe_small_long(long_normalize(z));
 }
 
-PyObject *
-_PyLong_Add(PyLongObject *a, PyLongObject *b)
+static PyLongObject *
+long_add(PyLongObject *a, PyLongObject *b)
 {
     if (_PyLong_BothAreCompact(a, b)) {
-        return _PyLong_FromSTwoDigits(medium_value(a) + medium_value(b));
+        stwodigits z = medium_value(a) + medium_value(b);
+        return _PyLong_FromSTwoDigits(z);
     }
 
     PyLongObject *z;
@@ -3775,24 +3776,31 @@ _PyLong_Add(PyLongObject *a, PyLongObject *b)
         else
             z = x_add(a, b);
     }
-    return (PyObject *)z;
+    return z;
+}
+
+PyObject *
+_PyLong_Add(PyLongObject *a, PyLongObject *b)
+{
+    return (PyObject*)long_add(a, b);
 }
 
 static PyObject *
-long_add(PyLongObject *a, PyLongObject *b)
+long_add_method(PyObject *a, PyObject *b)
 {
     CHECK_BINOP(a, b);
-    return _PyLong_Add(a, b);
+    return (PyObject*)long_add((PyLongObject*)a, (PyLongObject*)b);
 }
 
-PyObject *
-_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
-{
-    PyLongObject *z;
 
+static PyLongObject *
+long_sub(PyLongObject *a, PyLongObject *b)
+{
     if (_PyLong_BothAreCompact(a, b)) {
         return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b));
     }
+
+    PyLongObject *z;
     if (_PyLong_IsNegative(a)) {
         if (_PyLong_IsNegative(b)) {
             z = x_sub(b, a);
@@ -3811,16 +3819,23 @@ _PyLong_Subtract(PyLongObject *a, PyLongObject *b)
         else
             z = x_sub(a, b);
     }
-    return (PyObject *)z;
+    return z;
+}
+
+PyObject *
+_PyLong_Subtract(PyLongObject *a, PyLongObject *b)
+{
+    return (PyObject*)long_sub(a, b);
 }
 
 static PyObject *
-long_sub(PyLongObject *a, PyLongObject *b)
+long_sub_method(PyObject *a, PyObject *b)
 {
     CHECK_BINOP(a, b);
-    return _PyLong_Subtract(a, b);
+    return (PyObject*)long_sub((PyLongObject*)a, (PyLongObject*)b);
 }
 
+
 /* Grade school multiplication, ignoring the signs.
  * Returns the absolute value of the product, or NULL if error.
  */
@@ -4236,32 +4251,35 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b)
     return NULL;
 }
 
-PyObject *
-_PyLong_Multiply(PyLongObject *a, PyLongObject *b)
-{
-    PyLongObject *z;
 
+static PyLongObject*
+long_mul(PyLongObject *a, PyLongObject *b)
+{
     /* fast path for single-digit multiplication */
     if (_PyLong_BothAreCompact(a, b)) {
         stwodigits v = medium_value(a) * medium_value(b);
         return _PyLong_FromSTwoDigits(v);
     }
 
-    z = k_mul(a, b);
+    PyLongObject *z = k_mul(a, b);
     /* Negate if exactly one of the inputs is negative. */
     if (!_PyLong_SameSign(a, b) && z) {
         _PyLong_Negate(&z);
-        if (z == NULL)
-            return NULL;
     }
-    return (PyObject *)z;
+    return z;
+}
+
+PyObject *
+_PyLong_Multiply(PyLongObject *a, PyLongObject *b)
+{
+    return (PyObject*)long_mul(a, b);
 }
 
 static PyObject *
-long_mul(PyLongObject *a, PyLongObject *b)
+long_mul_method(PyObject *a, PyObject *b)
 {
     CHECK_BINOP(a, b);
-    return _PyLong_Multiply(a, b);
+    return (PyObject*)long_mul((PyLongObject*)a, (PyLongObject*)b);
 }
 
 /* Fast modulo division for single-digit longs. */
@@ -4416,13 +4434,13 @@ l_divmod(PyLongObject *v, PyLongObject *w,
     if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
         (_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
         PyLongObject *temp;
-        temp = (PyLongObject *) long_add(mod, w);
+        temp = long_add(mod, w);
         Py_SETREF(mod, temp);
         if (mod == NULL) {
             Py_DECREF(div);
             return -1;
         }
-        temp = (PyLongObject *) long_sub(div, (PyLongObject *)_PyLong_GetOne());
+        temp = long_sub(div, (PyLongObject *)_PyLong_GetOne());
         if (temp == NULL) {
             Py_DECREF(mod);
             Py_DECREF(div);
@@ -4463,7 +4481,7 @@ l_mod(PyLongObject *v, PyLongObject *w, PyLongObject **pmod)
     if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) ||
         (_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) {
         PyLongObject *temp;
-        temp = (PyLongObject *) long_add(mod, w);
+        temp = long_add(mod, w);
         Py_SETREF(mod, temp);
         if (mod == NULL)
             return -1;
@@ -4841,7 +4859,7 @@ long_invmod(PyLongObject *a, PyLongObject *n)
         if (t == NULL) {
             goto Error;
         }
-        s = (PyLongObject *)long_sub(b, t);
+        s = long_sub(b, t);
         Py_DECREF(t);
         if (s == NULL) {
             goto Error;
@@ -5136,7 +5154,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
     }
 
     if (negativeOutput && !_PyLong_IsZero(z)) {
-        temp = (PyLongObject *)long_sub(z, c);
+        temp = long_sub(z, c);
         if (temp == NULL)
             goto Error;
         Py_SETREF(z, temp);
@@ -5159,13 +5177,15 @@ long_pow(PyObject *v, PyObject *w, PyObject *x)
 }
 
 static PyObject *
-long_invert(PyLongObject *v)
+long_invert(PyObject *self)
 {
+    PyLongObject *v = _PyLong_CAST(self);
+
     /* Implement ~x as -(x+1) */
-    PyLongObject *x;
     if (_PyLong_IsCompact(v))
-        return _PyLong_FromSTwoDigits(~medium_value(v));
-    x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_GetOne());
+        return (PyObject*)_PyLong_FromSTwoDigits(~medium_value(v));
+
+    PyLongObject *x = long_add(v, (PyLongObject *)_PyLong_GetOne());
     if (x == NULL)
         return NULL;
     _PyLong_Negate(&x);
@@ -5174,31 +5194,45 @@ long_invert(PyLongObject *v)
     return (PyObject *)x;
 }
 
-static PyObject *
+static PyLongObject *
 long_neg(PyLongObject *v)
 {
-    PyLongObject *z;
-    if (_PyLong_IsCompact(v))
+    if (_PyLong_IsCompact(v)) {
         return _PyLong_FromSTwoDigits(-medium_value(v));
-    z = (PyLongObject *)_PyLong_Copy(v);
-    if (z != NULL)
+    }
+
+    PyLongObject *z = (PyLongObject *)_PyLong_Copy(v);
+    if (z != NULL) {
         _PyLong_FlipSign(z);
-    return (PyObject *)z;
+    }
+    return z;
 }
 
 static PyObject *
+long_neg_method(PyObject *v)
+{
+    return (PyObject*)long_neg(_PyLong_CAST(v));
+}
+
+static PyLongObject*
 long_abs(PyLongObject *v)
 {
     if (_PyLong_IsNegative(v))
         return long_neg(v);
     else
-        return long_long((PyObject *)v);
+        return (PyLongObject*)long_long((PyObject *)v);
+}
+
+static PyObject *
+long_abs_method(PyObject *v)
+{
+    return (PyObject*)long_abs(_PyLong_CAST(v));
 }
 
 static int
-long_bool(PyLongObject *v)
+long_bool(PyObject *v)
 {
-    return !_PyLong_IsZero(v);
+    return !_PyLong_IsZero(_PyLong_CAST(v));
 }
 
 /* Inner function for both long_rshift and _PyLong_Rshift, shifting an
@@ -5224,7 +5258,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
         m = medium_value(a);
         shift = wordshift == 0 ? remshift : PyLong_SHIFT;
         x = m < 0 ? ~(~m >> shift) : m >> shift;
-        return _PyLong_FromSTwoDigits(x);
+        return (PyObject*)_PyLong_FromSTwoDigits(x);
     }
 
     a_negative = _PyLong_IsNegative(a);
@@ -5358,7 +5392,7 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
         stwodigits m = medium_value(a);
         // bypass undefined shift operator behavior
         stwodigits x = m < 0 ? -(-m << remshift) : m << remshift;
-        return _PyLong_FromSTwoDigits(x);
+        return (PyObject*)_PyLong_FromSTwoDigits(x);
     }
 
     oldsize = _PyLong_DigitCount(a);
@@ -5388,40 +5422,40 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
     return (PyObject *) maybe_small_long(z);
 }
 
+
 static PyObject *
-long_lshift(PyObject *a, PyObject *b)
+long_lshift_method(PyObject *aa, PyObject *bb)
 {
-    int64_t shiftby;
+    CHECK_BINOP(aa, bb);
+    PyLongObject *a = (PyLongObject*)aa;
+    PyLongObject *b = (PyLongObject*)bb;
 
-    CHECK_BINOP(a, b);
-
-    if (_PyLong_IsNegative((PyLongObject *)b)) {
+    if (_PyLong_IsNegative(b)) {
         PyErr_SetString(PyExc_ValueError, "negative shift count");
         return NULL;
     }
-    if (_PyLong_IsZero((PyLongObject *)a)) {
+    if (_PyLong_IsZero(a)) {
         return PyLong_FromLong(0);
     }
-    if (PyLong_AsInt64(b, &shiftby) < 0) {
+
+    int64_t shiftby;
+    if (PyLong_AsInt64(bb, &shiftby) < 0) {
         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
             PyErr_SetString(PyExc_OverflowError,
                             "too many digits in integer");
         }
         return NULL;
     }
-    return _PyLong_Lshift(a, shiftby);
+    return long_lshift_int64(a, shiftby);
 }
 
 /* Return a << shiftby. */
-PyObject *
-_PyLong_Lshift(PyObject *a, int64_t shiftby)
+static PyObject *
+long_lshift_int64(PyLongObject *a, int64_t shiftby)
 {
-    Py_ssize_t wordshift;
-    digit remshift;
-
-    assert(PyLong_Check(a));
     assert(shiftby >= 0);
-    if (_PyLong_IsZero((PyLongObject *)a)) {
+
+    if (_PyLong_IsZero(a)) {
         return PyLong_FromLong(0);
     }
 #if PY_SSIZE_T_MAX <= INT64_MAX / PyLong_SHIFT
@@ -5431,11 +5465,18 @@ _PyLong_Lshift(PyObject *a, int64_t shiftby)
         return NULL;
     }
 #endif
-    wordshift = (Py_ssize_t)(shiftby / PyLong_SHIFT);
-    remshift = (digit)(shiftby % PyLong_SHIFT);
-    return long_lshift1((PyLongObject *)a, wordshift, remshift);
+    Py_ssize_t wordshift = (Py_ssize_t)(shiftby / PyLong_SHIFT);
+    digit remshift = (digit)(shiftby % PyLong_SHIFT);
+    return long_lshift1(a, wordshift, remshift);
+}
+
+PyObject *
+_PyLong_Lshift(PyObject *a, int64_t shiftby)
+{
+    return long_lshift_int64(_PyLong_CAST(a), shiftby);
 }
 
+
 /* Compute two's complement of digit vector a[0:m], writing result to
    z[0:m].  The digit vector a need not be normalized, but should not
    be entirely zero.  a and z may point to the same digit vector. */
@@ -5583,7 +5624,7 @@ long_and(PyObject *a, PyObject *b)
     PyLongObject *x = (PyLongObject*)a;
     PyLongObject *y = (PyLongObject*)b;
     if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
-        return _PyLong_FromSTwoDigits(medium_value(x) & medium_value(y));
+        return (PyObject*)_PyLong_FromSTwoDigits(medium_value(x) & medium_value(y));
     }
     return long_bitwise(x, '&', y);
 }
@@ -5595,7 +5636,7 @@ long_xor(PyObject *a, PyObject *b)
     PyLongObject *x = (PyLongObject*)a;
     PyLongObject *y = (PyLongObject*)b;
     if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
-        return _PyLong_FromSTwoDigits(medium_value(x) ^ medium_value(y));
+        return (PyObject*)_PyLong_FromSTwoDigits(medium_value(x) ^ medium_value(y));
     }
     return long_bitwise(x, '^', y);
 }
@@ -5607,7 +5648,7 @@ long_or(PyObject *a, PyObject *b)
     PyLongObject *x = (PyLongObject*)a;
     PyLongObject *y = (PyLongObject*)b;
     if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) {
-        return _PyLong_FromSTwoDigits(medium_value(x) | medium_value(y));
+        return (PyObject*)_PyLong_FromSTwoDigits(medium_value(x) | medium_value(y));
     }
     return long_bitwise(x, '|', y);
 }
@@ -5641,10 +5682,10 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
     }
 
     /* Initial reduction: make sure that 0 <= b <= a. */
-    a = (PyLongObject *)long_abs(a);
+    a = long_abs(a);
     if (a == NULL)
         return NULL;
-    b = (PyLongObject *)long_abs(b);
+    b = long_abs(b);
     if (b == NULL) {
         Py_DECREF(a);
         return NULL;
@@ -6026,12 +6067,11 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b)
 
     /* compare twice the remainder with the divisor, to see
        if we need to adjust the quotient and remainder */
-    PyObject *one = _PyLong_GetOne();  // borrowed reference
-    twice_rem = long_lshift((PyObject *)rem, one);
+    twice_rem = long_lshift_int64(rem, 1);
     if (twice_rem == NULL)
         goto error;
     if (quo_is_neg) {
-        temp = long_neg((PyLongObject*)twice_rem);
+        temp = (PyObject*)long_neg((PyLongObject*)twice_rem);
         Py_SETREF(twice_rem, temp);
         if (twice_rem == NULL)
             goto error;
@@ -6042,18 +6082,19 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b)
     quo_is_odd = (quo->long_value.ob_digit[0] & 1) != 0;
     if ((_PyLong_IsNegative((PyLongObject *)b) ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) {
         /* fix up quotient */
+        PyObject *one = _PyLong_GetOne();  // borrowed reference
         if (quo_is_neg)
-            temp = long_sub(quo, (PyLongObject *)one);
+            temp = (PyObject*)long_sub(quo, (PyLongObject *)one);
         else
-            temp = long_add(quo, (PyLongObject *)one);
+            temp = (PyObject*)long_add(quo, (PyLongObject *)one);
         Py_SETREF(quo, (PyLongObject *)temp);
         if (quo == NULL)
             goto error;
         /* and remainder */
         if (quo_is_neg)
-            temp = long_add(rem, (PyLongObject *)b);
+            temp = (PyObject*)long_add(rem, (PyLongObject *)b);
         else
-            temp = long_sub(rem, (PyLongObject *)b);
+            temp = (PyObject*)long_sub(rem, (PyLongObject *)b);
         Py_SETREF(rem, (PyLongObject *)temp);
         if (rem == NULL)
             goto error;
@@ -6089,8 +6130,6 @@ static PyObject *
 int___round___impl(PyObject *self, PyObject *o_ndigits)
 /*[clinic end generated code: output=954fda6b18875998 input=30c2aec788263144]*/
 {
-    PyObject *temp, *result, *ndigits;
-
     /* To round an integer m to the nearest 10**n (n positive), we make use of
      * the divmod_near operation, defined by:
      *
@@ -6108,7 +6147,7 @@ int___round___impl(PyObject *self, PyObject *o_ndigits)
     if (o_ndigits == Py_None)
         return long_long(self);
 
-    ndigits = _PyNumber_Index(o_ndigits);
+    PyObject *ndigits = _PyNumber_Index(o_ndigits);
     if (ndigits == NULL)
         return NULL;
 
@@ -6119,12 +6158,12 @@ int___round___impl(PyObject *self, PyObject *o_ndigits)
     }
 
     /* result = self - divmod_near(self, 10 ** -ndigits)[1] */
-    temp = long_neg((PyLongObject*)ndigits);
+    PyObject *temp = (PyObject*)long_neg((PyLongObject*)ndigits);
     Py_SETREF(ndigits, temp);
     if (ndigits == NULL)
         return NULL;
 
-    result = PyLong_FromLong(10L);
+    PyObject *result = PyLong_FromLong(10);
     if (result == NULL) {
         Py_DECREF(ndigits);
         return NULL;
@@ -6141,8 +6180,8 @@ int___round___impl(PyObject *self, PyObject *o_ndigits)
     if (result == NULL)
         return NULL;
 
-    temp = long_sub((PyLongObject *)self,
-                    (PyLongObject *)PyTuple_GET_ITEM(result, 1));
+    temp = (PyObject*)long_sub((PyLongObject*)self,
+                               (PyLongObject*)PyTuple_GET_ITEM(result, 1));
     Py_SETREF(result, temp);
 
     return result;
@@ -6475,18 +6514,18 @@ Base 0 means to interpret the base from the string as an integer literal.\n\
 4");
 
 static PyNumberMethods long_as_number = {
-    (binaryfunc)long_add,       /*nb_add*/
-    (binaryfunc)long_sub,       /*nb_subtract*/
-    (binaryfunc)long_mul,       /*nb_multiply*/
+    long_add_method,            /*nb_add*/
+    long_sub_method,            /*nb_subtract*/
+    long_mul_method,            /*nb_multiply*/
     long_mod,                   /*nb_remainder*/
     long_divmod,                /*nb_divmod*/
     long_pow,                   /*nb_power*/
-    (unaryfunc)long_neg,        /*nb_negative*/
+    long_neg_method,            /*nb_negative*/
     long_long,                  /*tp_positive*/
-    (unaryfunc)long_abs,        /*tp_absolute*/
-    (inquiry)long_bool,         /*tp_bool*/
-    (unaryfunc)long_invert,     /*nb_invert*/
-    long_lshift,                /*nb_lshift*/
+    long_abs_method,            /*tp_absolute*/
+    long_bool,                  /*tp_bool*/
+    long_invert,                /*nb_invert*/
+    long_lshift_method,         /*nb_lshift*/
     long_rshift,                /*nb_rshift*/
     long_and,                   /*nb_and*/
     long_xor,                   /*nb_xor*/