Skip to content

Commit 7089321

Browse files
extern-fn-struct-passing-abi test: ensure we don't start passing struct with natural alignment > 8 by reference
1 parent 8ec90f6 commit 7089321

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

tests/run-make/extern-fn-struct-passing-abi/test.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ struct Huge {
2828
int32_t e;
2929
};
3030

31+
struct Huge64 {
32+
int64_t a;
33+
int64_t b;
34+
int64_t c;
35+
int64_t d;
36+
int64_t e;
37+
};
38+
3139
struct FloatPoint {
3240
double x;
3341
double y;
@@ -152,6 +160,21 @@ void byval_rect_with_many_huge(struct Huge a, struct Huge b, struct Huge c,
152160
assert(g.d == 420);
153161
}
154162

163+
// System V x86_64 ABI:
164+
// a, b, d, e, f should be byval pointer (on the stack)
165+
// g passed via register (fixes #41375)
166+
//
167+
// i686-windows ABI:
168+
// a, b, d, e, f, g should be byval pointer
169+
void byval_rect_with_many_huge64(struct Huge64 a, struct Huge64 b, struct Huge64 c,
170+
struct Huge64 d, struct Huge64 e, struct Huge64 f,
171+
struct Rect g) {
172+
assert(g.a == 1234);
173+
assert(g.b == 4567);
174+
assert(g.c == 7890);
175+
assert(g.d == 4209);
176+
}
177+
155178
// System V x86_64 & Win64 ABI:
156179
// a, b should be in registers
157180
// s should be split across 2 integer registers
@@ -279,6 +302,19 @@ struct Huge huge_struct(struct Huge s) {
279302
return s;
280303
}
281304

305+
// System V x86_64 & i686-windows ABI:
306+
// s should be byval pointer
307+
// return should in a hidden sret pointer
308+
struct Huge64 huge64_struct(struct Huge64 s) {
309+
assert(s.a == 1234);
310+
assert(s.b == 1335);
311+
assert(s.c == 1436);
312+
assert(s.d == 1537);
313+
assert(s.e == 1638);
314+
315+
return s;
316+
}
317+
282318
// System V x86_64 ABI:
283319
// p should be in registers
284320
// return should be in registers

tests/run-make/extern-fn-struct-passing-abi/test.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ struct Huge {
3636
e: i32,
3737
}
3838

39+
#[derive(Clone, Copy, Debug, PartialEq)]
40+
#[repr(C)]
41+
struct Huge64 {
42+
a: i64,
43+
b: i64,
44+
c: i64,
45+
d: i64,
46+
e: i64,
47+
}
48+
3949
#[derive(Clone, Copy, Debug, PartialEq)]
4050
#[repr(C)]
4151
struct FloatPoint {
@@ -79,6 +89,8 @@ extern "C" {
7989

8090
fn byval_rect_with_many_huge(a: Huge, b: Huge, c: Huge, d: Huge, e: Huge, f: Huge, g: Rect);
8191

92+
fn byval_rect_with_many_huge64(a: Huge64, b: Huge64, c: Huge64, d: Huge64, e: Huge64, f: Huge64, g: Rect);
93+
8294
fn split_rect(a: i32, b: i32, s: Rect);
8395

8496
fn split_rect_floats(a: f32, b: f32, s: FloatRect);
@@ -95,6 +107,8 @@ extern "C" {
95107

96108
fn huge_struct(s: Huge) -> Huge;
97109

110+
fn huge64_struct(s: Huge64) -> Huge64;
111+
98112
fn float_point(p: FloatPoint) -> FloatPoint;
99113

100114
fn float_one(f: FloatOne) -> FloatOne;
@@ -107,6 +121,7 @@ fn main() {
107121
let t = BiggerRect { s: s, a: 27834, b: 7657 };
108122
let u = FloatRect { a: 3489, b: 3490, c: 8. };
109123
let v = Huge { a: 5647, b: 5648, c: 5649, d: 5650, e: 5651 };
124+
let w = Huge64 { a: 1234, b: 1335, c: 1436, d: 1537, e: 1638 };
110125
let p = FloatPoint { x: 5., y: -3. };
111126
let f1 = FloatOne { x: 7. };
112127
let i = IntOdd { a: 1, b: 2, c: 3 };
@@ -117,12 +132,14 @@ fn main() {
117132
byval_rect_floats(1., 2., 3., 4., 5., 6., 7., s, u);
118133
byval_rect_with_float(1, 2, 3.0, 4, 5, 6, s);
119134
byval_rect_with_many_huge(v, v, v, v, v, v, Rect { a: 123, b: 456, c: 789, d: 420 });
135+
byval_rect_with_many_huge64(w, w, w, w, w, w, Rect { a: 1234, b: 4567, c: 7890, d: 4209 });
120136
split_rect(1, 2, s);
121137
split_rect_floats(1., 2., u);
122138
split_rect_with_floats(1, 2, 3.0, 4, 5.0, 6, s);
123139
split_and_byval_rect(1, 2, 3, s, s);
124140
split_rect(1, 2, s);
125141
assert_eq!(huge_struct(v), v);
142+
assert_eq!(huge64_struct(w), w);
126143
assert_eq!(split_ret_byval_struct(1, 2, s), s);
127144
assert_eq!(sret_byval_struct(1, 2, 3, 4, s), t);
128145
assert_eq!(sret_split_struct(1, 2, s), t);

0 commit comments

Comments
 (0)