From 45da2fcbcd0ecaba673275d22b04fac3e4376e22 Mon Sep 17 00:00:00 2001 From: Sergei Trofimovich Date: Sat, 17 Feb 2018 18:53:02 +0000 Subject: [PATCH] new test: return small struct The bug originally was discovered in https://bugs.gentoo.org/634190 where complicated callback was returning invalid data on ia64. This change adds minimal reproducer that fails only on ia64 as: FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O0 execution test FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O2 execution test FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -O3 execution test FAIL: libffi.call/struct10.c -W -Wall -Wno-psabi -Os execution test Test passes on amd64. The fix is in the following commit. Bug: https://bugs.gentoo.org/634190 Signed-off-by: Sergei Trofimovich --- testsuite/Makefile.am | 1 + testsuite/libffi.call/struct10.c | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 testsuite/libffi.call/struct10.c diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 5eecc575..b367b46f 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -68,6 +68,7 @@ libffi.call/float4.c \ libffi.call/return_ldl.c \ libffi.call/closure_fn5.c \ libffi.call/struct6.c libffi.call/return_ll.c libffi.call/struct9.c \ +libffi.call/struct10.c \ libffi.call/return_sc.c libffi.call/struct7.c \ libffi.call/cls_align_uint64.c libffi.call/cls_4byte.c \ libffi.call/cls_6_1_byte.c \ diff --git a/testsuite/libffi.call/struct10.c b/testsuite/libffi.call/struct10.c new file mode 100644 index 00000000..17b13774 --- /dev/null +++ b/testsuite/libffi.call/struct10.c @@ -0,0 +1,57 @@ +/* Area: ffi_call + Purpose: Check structures. + Limitations: none. + PR: none. + Originator: Sergei Trofimovich + + The test originally discovered in ruby's bindings + for ffi in https://bugs.gentoo.org/634190 */ + +/* { dg-do run } */ +#include "ffitest.h" + +struct s { + int s32; + float f32; + signed char s8; +}; + +struct s make_s(void) { + struct s r; + r.s32 = 0x1234; + r.f32 = 7.0; + r.s8 = 0x78; + return r; +} + +int main() { + ffi_cif cif; + struct s r; + ffi_type rtype; + ffi_type* s_fields[] = { + &ffi_type_sint, + &ffi_type_float, + &ffi_type_schar, + NULL, + }; + + rtype.size = 0; + rtype.alignment = 0, + rtype.type = FFI_TYPE_STRUCT, + rtype.elements = s_fields, + + r.s32 = 0xbad; + r.f32 = 999.999; + r.s8 = 0x51; + + // Here we emulate the following call: + //r = make_s(); + + CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &rtype, NULL) == FFI_OK); + ffi_call(&cif, FFI_FN(make_s), &r, NULL); + + CHECK(r.s32 == 0x1234); + CHECK(r.f32 == 7.0); + CHECK(r.s8 == 0x78); + exit(0); +}