about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-07-04 19:31:52 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-07-05 13:24:25 +0300
commit050a71b570e49106e8dd6f6282e322220a5edf6f (patch)
tree61d2f42d3a03bdb42c054ad4508f46d777beca69 /src/test
parentb43eb4235ac43c822d903ad26ed806f34cc1a14a (diff)
downloadrust-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.c23
-rw-r--r--src/test/run-pass/abi-sysv64-arg-passing.rs36
-rw-r--r--src/test/run-pass/abi/issues/issue-62350-sysv-neg-reg-counts.rs46
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();
+}