bpo-31338 (#3374)

* Add Py_UNREACHABLE() as an alias to abort().
* Use Py_UNREACHABLE() instead of assert(0)
* Convert more unreachable code to use Py_UNREACHABLE()
* Document Py_UNREACHABLE() and a few other macros.
diff --git a/Python/ast.c b/Python/ast.c
index 7d30e5f..fd42c00 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -100,8 +100,7 @@
     case Param:
         return "Param";
     default:
-        assert(0);
-        return "(unknown)";
+        Py_UNREACHABLE();
     }
 }
 
@@ -759,8 +758,7 @@
             Py_FatalError(buf);
         }
     }
-    assert(0);
-    return 0;
+    Py_UNREACHABLE();
 }
 
 /* Transform the CST rooted at node * to the appropriate AST
diff --git a/Python/ceval.c b/Python/ceval.c
index 08533a4..5b810f2 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -274,7 +274,7 @@
         if (_Py_IsFinalizing() && !_Py_CURRENTLY_FINALIZING(tstate)) {
             drop_gil(tstate);
             PyThread_exit_thread();
-            assert(0);  /* unreachable */
+            Py_UNREACHABLE();
         }
         errno = err;
     }
@@ -3430,7 +3430,7 @@
 
         /* This should never be reached. Every opcode should end with DISPATCH()
            or goto error. */
-        assert(0);
+        Py_UNREACHABLE();
 
 error:
 
diff --git a/Python/compile.c b/Python/compile.c
index e547c2f..df5070a 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1350,8 +1350,7 @@
     case NameConstant_kind:
         return e->v.NameConstant.value;
     default:
-        assert(!is_const(e));
-        return NULL;
+        Py_UNREACHABLE();
     }
 }
 
diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c
index 9192bfd..2df7494 100644
--- a/Python/formatter_unicode.c
+++ b/Python/formatter_unicode.c
@@ -351,8 +351,7 @@
         *n_lpadding = 0;
     else {
         /* We should never have an unspecified alignment. */
-        *n_lpadding = 0;
-        assert(0);
+        Py_UNREACHABLE();
     }
 
     *n_rpadding = *n_total - nchars - *n_lpadding;
@@ -569,9 +568,7 @@
             break;
         default:
             /* Shouldn't get here, but treat it as '>' */
-            spec->n_lpadding = n_padding;
-            assert(0);
-            break;
+            Py_UNREACHABLE();
         }
     }
 
diff --git a/Python/pyhash.c b/Python/pyhash.c
index a2ec230..8a6bd60 100644
--- a/Python/pyhash.c
+++ b/Python/pyhash.c
@@ -175,7 +175,7 @@
             case 2: hash = ((hash << 5) + hash) + *p++; /* fallthrough */
             case 1: hash = ((hash << 5) + hash) + *p++; break;
             default:
-                assert(0);
+                Py_UNREACHABLE();
         }
         hash ^= len;
         hash ^= (Py_uhash_t) _Py_HashSecret.djbx33a.suffix;
diff --git a/Python/pystrtod.c b/Python/pystrtod.c
index 64d0c52..f19d239 100644
--- a/Python/pystrtod.c
+++ b/Python/pystrtod.c
@@ -431,8 +431,8 @@
   error:
     PyMem_Free(dup);
     PyErr_Format(PyExc_ValueError,
-		 "could not convert string to %s: "
-		 "%R", what, obj);
+                 "could not convert string to %s: "
+                 "%R", what, obj);
     return NULL;
 }
 
@@ -1061,7 +1061,7 @@
                something starting with a digit, an 'I',  or 'N' */
             strncpy(p, "ERR", 3);
             /* p += 3; */
-            assert(0);
+            Py_UNREACHABLE();
         }
         goto exit;
     }
diff --git a/Python/pytime.c b/Python/pytime.c
index 7edb534..8f275d2 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -630,10 +630,7 @@
     _PyTime_t t;
     if (pygettimeofday(&t, NULL, 0) < 0) {
         /* should not happen, _PyTime_Init() checked the clock at startup */
-        assert(0);
-
-        /* use a fixed value instead of a random value from the stack */
-        t = 0;
+        Py_UNREACHABLE();
     }
     return t;
 }
@@ -663,7 +660,7 @@
             return -1;
         }
         /* Hello, time traveler! */
-        assert(0);
+        Py_UNREACHABLE();
     }
     *tp = t * MS_TO_NS;
 
@@ -771,10 +768,7 @@
     if (pymonotonic(&t, NULL, 0) < 0) {
         /* should not happen, _PyTime_Init() checked that monotonic clock at
            startup */
-        assert(0);
-
-        /* use a fixed value instead of a random value from the stack */
-        t = 0;
+        Py_UNREACHABLE();
     }
     return t;
 }
diff --git a/Python/wordcode_helpers.h b/Python/wordcode_helpers.h
index cce81c1..c8f7a0f 100644
--- a/Python/wordcode_helpers.h
+++ b/Python/wordcode_helpers.h
@@ -39,6 +39,6 @@
             *codestr++ = PACKOPARG(opcode, oparg & 0xff);
             break;
         default:
-            assert(0);
+            Py_UNREACHABLE();
     }
 }