From 8315ea579046727bb234dc4692ca28c8514eacbe Mon Sep 17 00:00:00 2001
From: Tim Peters <tim.peters@gmail.com>
Date: Sun, 23 Jul 2000 19:28:35 +0000
Subject: [PATCH] Included assert.h in Python.h -- it's absurd that this basic
 tool of good C practice hasn't been available to everything all along. Added
 Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) macro to pyport.h; this just casts
 VALUE from type WIDE to type NARROW, but assert-fails if Py_DEBUG is defined
 and info is lost due to casting. Replaced a line in Fredrik's fix to
 marshal.c to use the new macro.

---
 Include/Python.h |  4 +++-
 Include/pyport.h | 17 +++++++++++++++++
 Python/marshal.c |  2 +-
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/Include/Python.h b/Include/Python.h
index 3cea5914d3..8ba466fe42 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -31,7 +31,6 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
 #include "patchlevel.h"
 #include "config.h"
-#include "pyport.h"
 
 /* config.h may or may not define DL_IMPORT */
 #ifndef DL_IMPORT	/* declarations for DLL import/export */
@@ -51,6 +50,9 @@ redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#include <assert.h>
+
+#include "pyport.h"
 
 #include "myproto.h"
 
diff --git a/Include/pyport.h b/Include/pyport.h
index 4faba7c9f0..ed8a28eb7b 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -27,6 +27,10 @@ RETSIGTYPE
 Meaning:  Expands to void or int, depending on what the platform wants
           signal handlers to return.  Note that only void is ANSI!
 Used in:  Py_RETURN_FROM_SIGNAL_HANDLER
+
+Py_DEBUG
+Meaning:  Extra checks compiled in for debug mode.
+Used in:  Py_SAFE_DOWNCAST
 **************************************************************************/
 
 
@@ -74,6 +78,19 @@ extern "C" {
 #define Py_RETURN_FROM_SIGNAL_HANDLER(VALUE) \
         Py_FORCE_EXPANSION(RETSIGTYPE) ## _PySIGRETURN(VALUE)
 
+/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW)
+ * Cast VALUE to type NARROW from type WIDE.  In Py_DEBUG mode, this
+ * assert-fails if any information is lost.
+ * Caution:
+ *    VALUE may be evaluated more than once.
+ */
+#ifdef Py_DEBUG
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \
+	(assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE))
+#else
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Python/marshal.c b/Python/marshal.c
index 74c547417a..f6447131d0 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -69,7 +69,7 @@ w_more(int c, WFILE *p)
 		p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
 		p->end =
 			PyString_AS_STRING((PyStringObject *)p->str) + newsize;
-		*p->ptr++ = (char) c;
+		*p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
 	}
 }
 
-- 
2.40.0