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]

Reply via email to