summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Behnel <stefan_ml@behnel.de>2021-09-01 00:09:02 +0200
committerStefan Behnel <stefan_ml@behnel.de>2021-09-01 09:15:00 +0200
commit54b0bf52a86126a98d76823dbc5d780f7e940895 (patch)
treee3c72947483a191bb413bf8989644ddcbabd762e
parentbf4979e2441ffbc9aaeb88f5c67608578040588f (diff)
downloadcython-54b0bf52a86126a98d76823dbc5d780f7e940895.tar.gz
Avoid copying unaligned 16-bit values since some platforms require them to be aligned. Use memcpy() instead to let the C compiler decide how to do it.
Closes https://github.com/cython/cython/issues/4343
-rw-r--r--Cython/Utility/TypeConversion.c17
1 files changed, 3 insertions, 14 deletions
diff --git a/Cython/Utility/TypeConversion.c b/Cython/Utility/TypeConversion.c
index 42e474443..7ccb67263 100644
--- a/Cython/Utility/TypeConversion.c
+++ b/Cython/Utility/TypeConversion.c
@@ -702,22 +702,11 @@ static const char DIGITS_HEX[2*16+1] = {
static CYTHON_INLINE PyObject* {{TO_PY_FUNCTION}}({{TYPE}} value, Py_ssize_t width, char padding_char, char format_char);
/////////////// CIntToPyUnicode ///////////////
+//@requires: StringTools.c::IncludeStringH
//@requires: StringTools.c::BuildPyUnicode
//@requires: CIntToDigits
//@requires: GCCDiagnostics
-#ifdef _MSC_VER
- #ifndef _MSC_STDINT_H_
- #if _MSC_VER < 1300
- typedef unsigned short uint16_t;
- #else
- typedef unsigned __int16 uint16_t;
- #endif
- #endif
-#else
- #include <stdint.h>
-#endif
-
// NOTE: inlining because most arguments are constant, which collapses lots of code below
static CYTHON_INLINE PyObject* {{TO_PY_FUNCTION}}({{TYPE}} value, Py_ssize_t width, char padding_char, char format_char) {
@@ -755,14 +744,14 @@ static CYTHON_INLINE PyObject* {{TO_PY_FUNCTION}}({{TYPE}} value, Py_ssize_t wid
digit_pos = abs((int)(remaining % (8*8)));
remaining = ({{TYPE}}) (remaining / (8*8));
dpos -= 2;
- *(uint16_t*)dpos = ((const uint16_t*)DIGIT_PAIRS_8)[digit_pos]; /* copy 2 digits at a time */
+ memcpy(dpos, DIGIT_PAIRS_8 + digit_pos * 2, 2); /* copy 2 digits at a time, unaligned */
last_one_off = (digit_pos < 8);
break;
case 'd':
digit_pos = abs((int)(remaining % (10*10)));
remaining = ({{TYPE}}) (remaining / (10*10));
dpos -= 2;
- *(uint16_t*)dpos = ((const uint16_t*)DIGIT_PAIRS_10)[digit_pos]; /* copy 2 digits at a time */
+ memcpy(dpos, DIGIT_PAIRS_10 + digit_pos * 2, 2); /* copy 2 digits at a time, unaligned */
last_one_off = (digit_pos < 10);
break;
case 'x':