Issue #12973: Fix int.__pow__ overflow checks that invoked undefined behaviour, thereby producing incorrect results on Clang.
diff --git a/Misc/NEWS b/Misc/NEWS
index 2b67883..72d7a09 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -9,6 +9,11 @@
 Core and Builtins
 -----------------
 
+- Issue #12973: Fix overflow checks that invoked undefined behaviour in
+  int.__pow__.  These overflow checks were causing int.__pow__ to produce
+  incorrect results with recent versions of Clang, as a result of the
+  compiler optimizing the check away.
+
 - Issue #12266: Fix str.capitalize() to correctly uppercase/lowercase
   titlecased and cased non-letter characters.
 
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 7d70bfb..e518e74 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -751,7 +751,13 @@
     while (iw > 0) {
         prev = ix;              /* Save value for overflow check */
         if (iw & 1) {
-            ix = ix*temp;
+            /*
+             * The (unsigned long) cast below ensures that the multiplication
+             * is interpreted as an unsigned operation rather than a signed one
+             * (C99 6.3.1.8p1), thus avoiding the perils of undefined behaviour
+             * from signed arithmetic overflow (C99 6.5p5).  See issue #12973.
+             */
+            ix = (unsigned long)ix * temp;
             if (temp == 0)
                 break; /* Avoid ix / 0 */
             if (ix / temp != prev) {
@@ -764,7 +770,7 @@
         iw >>= 1;               /* Shift exponent down by 1 bit */
         if (iw==0) break;
         prev = temp;
-        temp *= temp;           /* Square the value of temp */
+        temp = (unsigned long)temp * temp;  /* Square the value of temp */
         if (prev != 0 && temp / prev != prev) {
             return PyLong_Type.tp_as_number->nb_power(
                 (PyObject *)v, (PyObject *)w, (PyObject *)z);