Issue #7767: Add new C-API function PyLong_AsLongLongAndOverflow, a
long long variant of PyLong_AsLongAndOverflow.  Patch by Case Van
Horsen.
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index f0dd75e..7aa5758 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -523,6 +523,171 @@
 	return Py_None;
 }
 
+/* Test the PyLong_AsLongLongAndOverflow API. General conversion to
+   PY_LONG_LONG is tested by test_long_api_inner. This test will
+   concentrate on proper handling of overflow.
+*/
+
+static PyObject *
+test_long_long_and_overflow(PyObject *self)
+{
+	PyObject *num, *one, *temp;
+	PY_LONG_LONG value;
+	int overflow;
+
+	/* Test that overflow is set properly for a large value. */
+	/* num is a number larger than PY_LLONG_MAX on a typical machine. */
+	num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
+	if (num == NULL)
+		return NULL;
+	overflow = 1234;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != -1)
+		return raiseTestError("test_long_long_and_overflow",
+			"return value was not set to -1");
+	if (overflow != 1)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was not set to 1");
+
+	/* Same again, with num = PY_LLONG_MAX + 1 */
+	num = PyLong_FromLongLong(PY_LLONG_MAX);
+	if (num == NULL)
+		return NULL;
+	one = PyLong_FromLong(1L);
+	if (one == NULL) {
+		Py_DECREF(num);
+		return NULL;
+	}
+	temp = PyNumber_Add(num, one);
+	Py_DECREF(one);
+	Py_DECREF(num);
+	num = temp;
+	if (num == NULL)
+		return NULL;
+	overflow = 0;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != -1)
+		return raiseTestError("test_long_long_and_overflow",
+			"return value was not set to -1");
+	if (overflow != 1)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was not set to 1");
+
+	/* Test that overflow is set properly for a large negative value. */
+	/* num is a number smaller than PY_LLONG_MIN on a typical platform */
+	num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16);
+	if (num == NULL)
+		return NULL;
+	overflow = 1234;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != -1)
+		return raiseTestError("test_long_long_and_overflow",
+			"return value was not set to -1");
+	if (overflow != -1)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was not set to -1");
+
+	/* Same again, with num = PY_LLONG_MIN - 1 */
+	num = PyLong_FromLongLong(PY_LLONG_MIN);
+	if (num == NULL)
+		return NULL;
+	one = PyLong_FromLong(1L);
+	if (one == NULL) {
+		Py_DECREF(num);
+		return NULL;
+	}
+	temp = PyNumber_Subtract(num, one);
+	Py_DECREF(one);
+	Py_DECREF(num);
+	num = temp;
+	if (num == NULL)
+		return NULL;
+	overflow = 0;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != -1)
+		return raiseTestError("test_long_long_and_overflow",
+			"return value was not set to -1");
+	if (overflow != -1)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was not set to -1");
+
+ 	/* Test that overflow is cleared properly for small values. */
+	num = PyLong_FromString("FF", NULL, 16);
+	if (num == NULL)
+		return NULL;
+	overflow = 1234;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != 0xFF)
+		return raiseTestError("test_long_long_and_overflow",
+			"expected return value 0xFF");
+	if (overflow != 0)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was not cleared");
+
+	num = PyLong_FromString("-FF", NULL, 16);
+	if (num == NULL)
+		return NULL;
+	overflow = 0;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != -0xFF)
+		return raiseTestError("test_long_long_and_overflow",
+			"expected return value 0xFF");
+	if (overflow != 0)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was set incorrectly");
+
+	num = PyLong_FromLongLong(PY_LLONG_MAX);
+	if (num == NULL)
+		return NULL;
+	overflow = 1234;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != PY_LLONG_MAX)
+		return raiseTestError("test_long_long_and_overflow",
+			"expected return value PY_LLONG_MAX");
+	if (overflow != 0)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was not cleared");
+
+	num = PyLong_FromLongLong(PY_LLONG_MIN);
+	if (num == NULL)
+		return NULL;
+	overflow = 0;
+	value = PyLong_AsLongLongAndOverflow(num, &overflow);
+	Py_DECREF(num);
+	if (value == -1 && PyErr_Occurred())
+		return NULL;
+	if (value != PY_LLONG_MIN)
+		return raiseTestError("test_long_long_and_overflow",
+			"expected return value PY_LLONG_MIN");
+	if (overflow != 0)
+		return raiseTestError("test_long_long_and_overflow",
+			"overflow was not cleared");
+
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
 /* Test the L code for PyArg_ParseTuple.  This should deliver a PY_LONG_LONG
    for both long and int arguments.  The test may leak a little memory if
    it fails.
@@ -1252,6 +1417,8 @@
 	{"getargs_L",		getargs_L,			 METH_VARARGS},
 	{"getargs_K",		getargs_K,			 METH_VARARGS},
 	{"test_longlong_api",	test_longlong_api,		 METH_NOARGS},
+	{"test_long_long_and_overflow",
+		(PyCFunction)test_long_long_and_overflow, METH_NOARGS},
 	{"test_L_code",		(PyCFunction)test_L_code,	 METH_NOARGS},
 	{"codec_incrementalencoder",
 	 (PyCFunction)codec_incrementalencoder,	 METH_VARARGS},