bpo-40887: Don't use finalized free lists (GH-20700)

In debug mode, ensure that free lists are no longer used after being
finalized. Set numfree to -1 in finalization functions
(eg. _PyList_Fini()), and then check that numfree is not equal to -1
before using a free list (e.g list_dealloc()).
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index d72fd21..65625fe 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -116,6 +116,10 @@
     struct _Py_float_state *state = &interp->float_state;
     PyFloatObject *op = state->free_list;
     if (op != NULL) {
+#ifdef Py_DEBUG
+        // PyFloat_FromDouble() must not be called after _PyFloat_Fini()
+        assert(state->numfree != -1);
+#endif
         state->free_list = (PyFloatObject *) Py_TYPE(op);
         state->numfree--;
     }
@@ -219,6 +223,10 @@
     if (PyFloat_CheckExact(op)) {
         PyInterpreterState *interp = _PyInterpreterState_GET();
         struct _Py_float_state *state = &interp->float_state;
+#ifdef Py_DEBUG
+        // float_dealloc() must not be called after _PyFloat_Fini()
+        assert(state->numfree != -1);
+#endif
         if (state->numfree >= PyFloat_MAXFREELIST)  {
             PyObject_FREE(op);
             return;
@@ -1984,10 +1992,11 @@
 _PyFloat_ClearFreeList(PyThreadState *tstate)
 {
     struct _Py_float_state *state = &tstate->interp->float_state;
-    PyFloatObject *f = state->free_list, *next;
-    for (; f; f = next) {
-        next = (PyFloatObject*) Py_TYPE(f);
+    PyFloatObject *f = state->free_list;
+    while (f != NULL) {
+        PyFloatObject *next = (PyFloatObject*) Py_TYPE(f);
         PyObject_FREE(f);
+        f = next;
     }
     state->free_list = NULL;
     state->numfree = 0;
@@ -1997,6 +2006,10 @@
 _PyFloat_Fini(PyThreadState *tstate)
 {
     _PyFloat_ClearFreeList(tstate);
+#ifdef Py_DEBUG
+    struct _Py_float_state *state = &tstate->interp->float_state;
+    state->numfree = -1;
+#endif
 }
 
 /* Print summary info about the state of the optimized allocator */