https://github.com/python/cpython/commit/91ba786ed777cfcd10c7e8c346ec8fe1f8278ae3
commit: 91ba786ed777cfcd10c7e8c346ec8fe1f8278ae3
branch: main
author: Stian Halseth <[email protected]>
committer: vstinner <[email protected]>
date: 2026-11-07T15:30:26+01:00
summary:
gh-161475: Fix ctypes structures with float arrays returned on Linux SPARC
(#161476)
On Linux, GCC and clang pass arrays of floating-point type in a structure
in integer registers; only Solaris follows the vendor ABI there (GCC PR
target/114416). Since gh-110190, ctypes described such array elements to
libffi as floats on all SPARC, so libffi read structures returned by value
from the FP registers on Linux.
files:
A Misc/NEWS.d/next/Library/2026-11-06-11-59-26.gh-issue-161475.82LWf4.rst
M Modules/_ctypes/stgdict.c
diff --git
a/Misc/NEWS.d/next/Library/2026-11-06-11-59-26.gh-issue-161475.82LWf4.rst
b/Misc/NEWS.d/next/Library/2026-11-06-11-59-26.gh-issue-161475.82LWf4.rst
new file mode 100644
index 000000000000000..3033bc7543b9016
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-11-06-11-59-26.gh-issue-161475.82LWf4.rst
@@ -0,0 +1,2 @@
+Fix :mod:`ctypes` structures containing arrays of floating-point type
+returned by value on 64-bit Linux SPARC.
diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c
index fc47844104876ea..7920c87ebe3cef3 100644
--- a/Modules/_ctypes/stgdict.c
+++ b/Modules/_ctypes/stgdict.c
@@ -683,10 +683,22 @@ _replace_array_elements(ctypes_state *st, PyObject
*layout_fields,
structs[struct_index].type = FFI_TYPE_STRUCT;
structs[struct_index].elements = &dummy_types[dummy_index];
++struct_index;
+ ffi_type *etype = &einfo->ffi_type_pointer;
+#if defined(__sparc__) && defined(__arch64__) && !defined(__sun)
+ /* On Linux, GCC and clang pass arrays of floating-point type
+ in a structure in integer registers; only Solaris follows
+ the vendor ABI here (GCC PR target/114416). */
+ if (etype->type == FFI_TYPE_FLOAT) {
+ etype = &ffi_type_uint32;
+ }
+ else if (etype->type == FFI_TYPE_DOUBLE) {
+ etype = &ffi_type_uint64;
+ }
+#endif
/* Copy over the element's type, length times. */
while (length > 0) {
assert(dummy_index < (num_ffi_type_pointers));
- dummy_types[dummy_index++] = &einfo->ffi_type_pointer;
+ dummy_types[dummy_index++] = etype;
length--;
}
assert(dummy_index < (num_ffi_type_pointers));
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]