diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2019-07-04 19:31:52 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2019-07-05 13:24:25 +0300 |
| commit | 050a71b570e49106e8dd6f6282e322220a5edf6f (patch) | |
| tree | 61d2f42d3a03bdb42c054ad4508f46d777beca69 /src/test | |
| parent | b43eb4235ac43c822d903ad26ed806f34cc1a14a (diff) | |
| download | rust-050a71b570e49106e8dd6f6282e322220a5edf6f.tar.gz rust-050a71b570e49106e8dd6f6282e322220a5edf6f.zip | |
rustc_target: avoid negative register counts in the SysV x86_64 ABI.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/auxiliary/rust_test_helpers.c | 23 | ||||
| -rw-r--r-- | src/test/run-pass/abi-sysv64-arg-passing.rs | 36 | ||||
| -rw-r--r-- | src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs | 46 |
3 files changed, 105 insertions, 0 deletions
diff --git a/src/test/auxiliary/rust_test_helpers.c b/src/test/auxiliary/rust_test_helpers.c index 7f2afd9c571..b95b0ca1a89 100644 --- a/src/test/auxiliary/rust_test_helpers.c +++ b/src/test/auxiliary/rust_test_helpers.c @@ -215,6 +215,29 @@ uint64_t get_c_many_params(void *a, void *b, void *c, void *d, struct quad f) { return f.c; } +struct quad_floats { + float a; + float b; + float c; + float d; +}; + +float get_c_exhaust_sysv64_ints( + void *a, + void *b, + void *c, + void *d, + void *e, + void *f, + // `f` used the last integer register, so `g` goes on the stack. + // It also used to bring the "count of available integer registers" down to + // `-1` which broke the next SSE-only aggregate argument (`h`) - see #62350. + void *g, + struct quad_floats h +) { + return h.c; +} + // Calculates the average of `(x + y) / n` where x: i64, y: f64. There must be exactly n pairs // passed as variadic arguments. There are two versions of this function: the // variadic one, and the one that takes a `va_list`. diff --git a/src/test/run-pass/abi-sysv64-arg-passing.rs b/src/test/run-pass/abi-sysv64-arg-passing.rs index 0b9f9934fa9..fdf0573b5e3 100644 --- a/src/test/run-pass/abi-sysv64-arg-passing.rs +++ b/src/test/run-pass/abi-sysv64-arg-passing.rs @@ -20,6 +20,7 @@ // extern-return-TwoU64s // foreign-fn-with-byval // issue-28676 +// issue-62350-sysv-neg-reg-counts // struct-return // ignore-android @@ -83,6 +84,9 @@ mod tests { #[derive(Copy, Clone)] pub struct Quad { a: u64, b: u64, c: u64, d: u64 } + #[derive(Copy, Clone)] + pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } + #[repr(C)] #[derive(Copy, Clone)] pub struct Floats { a: f64, b: u8, c: f64 } @@ -108,6 +112,16 @@ mod tests { pub fn get_z(x: S) -> u64; pub fn get_c_many_params(_: *const (), _: *const (), _: *const (), _: *const (), f: Quad) -> u64; + pub fn get_c_exhaust_sysv64_ints( + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + h: QuadFloats, + ) -> f32; pub fn rust_dbg_abi_1(q: Quad) -> Quad; pub fn rust_dbg_abi_2(f: Floats) -> Floats; } @@ -263,6 +277,27 @@ mod tests { test(); } + fn test_62350() { + use std::ptr; + unsafe { + let null = ptr::null(); + let q = QuadFloats { + a: 10.2, + b: 20.3, + c: 30.4, + d: 40.5 + }; + assert_eq!( + get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), + q.c, + ); + } + } + + pub fn issue_62350() { + test_62350(); + } + fn test1() { unsafe { let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa, @@ -321,6 +356,7 @@ fn main() { extern_return_twou64s(); foreign_fn_with_byval(); issue_28676(); + issue_62350(); struct_return(); } diff --git a/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs b/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs new file mode 100644 index 00000000000..df819306e4a --- /dev/null +++ b/src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs @@ -0,0 +1,46 @@ +// run-pass +#![allow(dead_code)] +#![allow(improper_ctypes)] + +// ignore-wasm32-bare no libc to test ffi with + +#[derive(Copy, Clone)] +pub struct QuadFloats { a: f32, b: f32, c: f32, d: f32 } + +mod rustrt { + use super::QuadFloats; + + #[link(name = "rust_test_helpers", kind = "static")] + extern { + pub fn get_c_exhaust_sysv64_ints( + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + _: *const (), + h: QuadFloats, + ) -> f32; + } +} + +fn test() { + unsafe { + let null = std::ptr::null(); + let q = QuadFloats { + a: 10.2, + b: 20.3, + c: 30.4, + d: 40.5 + }; + assert_eq!( + rustrt::get_c_exhaust_sysv64_ints(null, null, null, null, null, null, null, q), + q.c, + ); + } +} + +pub fn main() { + test(); +} |
