about summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Desjardins <erikdesjardins@users.noreply.github.com>2023-05-20 15:33:20 -0400
committerErik Desjardins <erikdesjardins@users.noreply.github.com>2023-07-10 19:19:38 -0400
commit7089321c6deabb3c25cf0ec829ca209f77b8ee5a (patch)
tree8494376e909ec06c80bf74f4122e37c0c4a62bf5
parent8ec90f6f14a5c2c8cc454e78f87b7fc6347fe2f8 (diff)
downloadrust-7089321c6deabb3c25cf0ec829ca209f77b8ee5a.tar.gz
rust-7089321c6deabb3c25cf0ec829ca209f77b8ee5a.zip
extern-fn-struct-passing-abi test: ensure we don't start passing struct with natural alignment > 8 by reference
-rw-r--r--tests/run-make/extern-fn-struct-passing-abi/test.c36
-rw-r--r--tests/run-make/extern-fn-struct-passing-abi/test.rs17
2 files changed, 53 insertions, 0 deletions
diff --git a/tests/run-make/extern-fn-struct-passing-abi/test.c b/tests/run-make/extern-fn-struct-passing-abi/test.c
index 136b07129e1..2cff776d86c 100644
--- a/tests/run-make/extern-fn-struct-passing-abi/test.c
+++ b/tests/run-make/extern-fn-struct-passing-abi/test.c
@@ -28,6 +28,14 @@ struct Huge {
     int32_t e;
 };
 
+struct Huge64 {
+    int64_t a;
+    int64_t b;
+    int64_t c;
+    int64_t d;
+    int64_t e;
+};
+
 struct FloatPoint {
     double x;
     double y;
@@ -152,6 +160,21 @@ void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
     assert(g.d == 420);
 }
 
+// System V x86_64 ABI:
+// a, b, d, e, f should be byval pointer (on the stack)
+// g passed via register (fixes #41375)
+//
+// i686-windows ABI:
+// a, b, d, e, f, g should be byval pointer
+void byval_rect_with_many_huge64(struct Huge64 a, struct Huge64 b, struct Huge64 c,
+                               struct Huge64 d, struct Huge64 e, struct Huge64 f,
+                               struct Rect g) {
+    assert(g.a == 1234);
+    assert(g.b == 4567);
+    assert(g.c == 7890);
+    assert(g.d == 4209);
+}
+
 // System V x86_64 & Win64 ABI:
 // a, b should be in registers
 // s should be split across 2 integer registers
@@ -279,6 +302,19 @@ struct Huge huge_struct(struct Huge s) {
     return s;
 }
 
+// System V x86_64 & i686-windows ABI:
+// s should be byval pointer
+// return should in a hidden sret pointer
+struct Huge64 huge64_struct(struct Huge64 s) {
+    assert(s.a == 1234);
+    assert(s.b == 1335);
+    assert(s.c == 1436);
+    assert(s.d == 1537);
+    assert(s.e == 1638);
+
+    return s;
+}
+
 // System V x86_64 ABI:
 // p should be in registers
 // return should be in registers
diff --git a/tests/run-make/extern-fn-struct-passing-abi/test.rs b/tests/run-make/extern-fn-struct-passing-abi/test.rs
index afe0f52ef0b..d58254301cc 100644
--- a/tests/run-make/extern-fn-struct-passing-abi/test.rs
+++ b/tests/run-make/extern-fn-struct-passing-abi/test.rs
@@ -38,6 +38,16 @@ struct Huge {
 
 #[derive(Clone, Copy, Debug, PartialEq)]
 #[repr(C)]
+struct Huge64 {
+    a: i64,
+    b: i64,
+    c: i64,
+    d: i64,
+    e: i64,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(C)]
 struct FloatPoint {
     x: f64,
     y: f64,
@@ -79,6 +89,8 @@ extern "C" {
 
     fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);
 
+    fn byval_rect_with_many_huge64(a: Huge64, b: Huge64, c: Huge64, d: Huge64, e: Huge64, f: Huge64, g: Rect);
+
     fn split_rect(a: i32, b: i32, s: Rect);
 
     fn split_rect_floats(a: f32, b: f32, s: FloatRect);
@@ -95,6 +107,8 @@ extern "C" {
 
     fn huge_struct(s: Huge) -> Huge;
 
+    fn huge64_struct(s: Huge64) -> Huge64;
+
     fn float_point(p: FloatPoint) -> FloatPoint;
 
     fn float_one(f: FloatOne) -> FloatOne;
@@ -107,6 +121,7 @@ fn main() {
     let t = BiggerRect { s: s, a: 27834, b: 7657 };
     let u = FloatRect { a: 3489, b: 3490, c: 8. };
     let v = Huge { a: 5647, b: 5648, c: 5649, d: 5650, e: 5651 };
+    let w = Huge64 { a: 1234, b: 1335, c: 1436, d: 1537, e: 1638 };
     let p = FloatPoint { x: 5., y: -3. };
     let f1 = FloatOne { x: 7. };
     let i = IntOdd { a: 1, b: 2, c: 3 };
@@ -117,12 +132,14 @@ fn main() {
         byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
         byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
         byval_rect_with_many_huge(v, v, v, v, v, v, Rect { a: 123, b: 456, c: 789, d: 420 });
+        byval_rect_with_many_huge64(w, w, w, w, w, w, Rect { a: 1234, b: 4567, c: 7890, d: 4209 });
         split_rect(1, 2, s);
         split_rect_floats(1., 2., u);
         split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
         split_and_byval_rect(1, 2, 3, s, s);
         split_rect(1, 2, s);
         assert_eq!(huge_struct(v), v);
+        assert_eq!(huge64_struct(w), w);
         assert_eq!(split_ret_byval_struct(1, 2, s), s);
         assert_eq!(sret_byval_struct(1, 2, 3, 4, s), t);
         assert_eq!(sret_split_struct(1, 2, s), t);