Skip to content

Commit e81a294

Browse files
committed
gh-161475: Fix ctypes structures with float arrays returned on Linux SPARC
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.
1 parent 3feccd1 commit e81a294

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix :mod:`ctypes` structures containing arrays of floating-point type
2+
returned by value on 64-bit Linux SPARC.

‎Modules/_ctypes/stgdict.c‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,10 +683,22 @@ _replace_array_elements(ctypes_state *st, PyObject *layout_fields,
683683
structs[struct_index].type = FFI_TYPE_STRUCT;
684684
structs[struct_index].elements = &dummy_types[dummy_index];
685685
++struct_index;
686+
ffi_type *etype = &einfo->ffi_type_pointer;
687+
#if defined(__sparc__) && defined(__arch64__) && !defined(__sun)
688+
/* On Linux, GCC and clang pass arrays of floating-point type
689+
in a structure in integer registers; only Solaris follows
690+
the vendor ABI here (GCC PR target/114416). */
691+
if (etype->type == FFI_TYPE_FLOAT) {
692+
etype = &ffi_type_uint32;
693+
}
694+
else if (etype->type == FFI_TYPE_DOUBLE) {
695+
etype = &ffi_type_uint64;
696+
}
697+
#endif
686698
/* Copy over the element's type, length times. */
687699
while (length > 0) {
688700
assert(dummy_index < (num_ffi_type_pointers));
689-
dummy_types[dummy_index++] = &einfo->ffi_type_pointer;
701+
dummy_types[dummy_index++] = etype;
690702
length--;
691703
}
692704
assert(dummy_index < (num_ffi_type_pointers));

0 commit comments

Comments
 (0)