]> git.lizzy.rs Git - rust.git/blob - src/test/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs
Rollup merge of #103012 - chenyukang:fix-102806, r=davidtwco,compiler-errors
[rust.git] / src / test / run-make-fulldeps / extern-fn-struct-passing-abi / test.rs
1 // Passing structs via FFI should work regardless of whether
2 // they get passed in multiple registers, byval pointers or the stack
3
4 #[derive(Clone, Copy, Debug, PartialEq)]
5 #[repr(C)]
6 struct Rect {
7     a: i32,
8     b: i32,
9     c: i32,
10     d: i32,
11 }
12
13 #[derive(Clone, Copy, Debug, PartialEq)]
14 #[repr(C)]
15 struct BiggerRect {
16     s: Rect,
17     a: i32,
18     b: i32,
19 }
20
21 #[derive(Clone, Copy, Debug, PartialEq)]
22 #[repr(C)]
23 struct FloatRect {
24     a: i32,
25     b: i32,
26     c: f64,
27 }
28
29 #[derive(Clone, Copy, Debug, PartialEq)]
30 #[repr(C)]
31 struct Huge {
32     a: i32,
33     b: i32,
34     c: i32,
35     d: i32,
36     e: i32,
37 }
38
39 #[derive(Clone, Copy, Debug, PartialEq)]
40 #[repr(C)]
41 struct FloatPoint {
42     x: f64,
43     y: f64,
44 }
45
46 #[derive(Clone, Copy, Debug, PartialEq)]
47 #[repr(C)]
48 struct FloatOne {
49     x: f64,
50 }
51
52 #[derive(Clone, Copy, Debug, PartialEq)]
53 #[repr(C)]
54 struct IntOdd {
55     a: i8,
56     b: i8,
57     c: i8,
58 }
59
60 #[link(name = "test", kind = "static")]
61 extern "C" {
62     fn byval_rect(a: i32, b: i32, c: i32, d: i32, e: i32, s: Rect);
63
64     fn byval_many_rect(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, s: Rect);
65
66     fn byval_rect_floats(
67         a: f32,
68         b: f32,
69         c: f64,
70         d: f32,
71         e: f32,
72         f: f32,
73         g: f64,
74         s: Rect,
75         t: FloatRect,
76     );
77
78     fn byval_rect_with_float(a: i32, b: i32, c: f32, d: i32, e: i32, f: i32, s: Rect);
79
80     fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);
81
82     fn split_rect(a: i32, b: i32, s: Rect);
83
84     fn split_rect_floats(a: f32, b: f32, s: FloatRect);
85
86     fn split_rect_with_floats(a: i32, b: i32, c: f32, d: i32, e: f32, f: i32, s: Rect);
87
88     fn split_and_byval_rect(a: i32, b: i32, c: i32, s: Rect, t: Rect);
89
90     fn split_ret_byval_struct(a: i32, b: i32, s: Rect) -> Rect;
91
92     fn sret_byval_struct(a: i32, b: i32, c: i32, d: i32, s: Rect) -> BiggerRect;
93
94     fn sret_split_struct(a: i32, b: i32, s: Rect) -> BiggerRect;
95
96     fn huge_struct(s: Huge) -> Huge;
97
98     fn float_point(p: FloatPoint) -> FloatPoint;
99
100     fn float_one(f: FloatOne) -> FloatOne;
101
102     fn int_odd(i: IntOdd) -> IntOdd;
103 }
104
105 fn main() {
106     let s = Rect { a: 553, b: 554, c: 555, d: 556 };
107     let t = BiggerRect { s: s, a: 27834, b: 7657 };
108     let u = FloatRect { a: 3489, b: 3490, c: 8. };
109     let v = Huge { a: 5647, b: 5648, c: 5649, d: 5650, e: 5651 };
110     let p = FloatPoint { x: 5., y: -3. };
111     let f1 = FloatOne { x: 7. };
112     let i = IntOdd { a: 1, b: 2, c: 3 };
113
114     unsafe {
115         byval_rect(1, 2, 3, 4, 5, s);
116         byval_many_rect(1, 2, 3, 4, 5, 6, s);
117         byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
118         byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
119         byval_rect_with_many_huge(v, v, v, v, v, v, Rect { a: 123, b: 456, c: 789, d: 420 });
120         split_rect(1, 2, s);
121         split_rect_floats(1., 2., u);
122         split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
123         split_and_byval_rect(1, 2, 3, s, s);
124         split_rect(1, 2, s);
125         assert_eq!(huge_struct(v), v);
126         assert_eq!(split_ret_byval_struct(1, 2, s), s);
127         assert_eq!(sret_byval_struct(1, 2, 3, 4, s), t);
128         assert_eq!(sret_split_struct(1, 2, s), t);
129         assert_eq!(float_point(p), p);
130         assert_eq!(int_odd(i), i);
131
132         // MSVC/GCC/Clang are not consistent in the ABI of single-float aggregates.
133         // x86_64: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82028
134         // i686: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82041
135         #[cfg(not(all(windows, target_env = "gnu")))]
136         assert_eq!(float_one(f1), f1);
137     }
138 }