Skip to content

Commit 46a719e

Browse files
Remove useless //ignore-arch directives on a compile-fail test, and add another test that checks if the sysv64 abi corresponds to the same rules as the C abi on unix platforms
1 parent d282a63 commit 46a719e

File tree

2 files changed

+341
-6
lines changed

2 files changed

+341
-6
lines changed

src/test/compile-fail/feature-gate-abi-sysv64.rs

-6
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,9 @@
1111
// Test that the sysv64 ABI cannot be used when abi-sysv64 feature
1212
// gate is not used.
1313

14-
// ignore-android
15-
// ignore-arm
16-
// ignore-aarch64
17-
18-
#[cfg(target_arch = "x86_64")]
1914
extern "sysv64" fn foo() {}
2015
//~^ ERROR sysv64 ABI is experimental and subject to change
2116

22-
#[cfg(target_arch = "x86_64")]
2317
fn main() {
2418
foo();
2519
}
+341
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Checks if the "sysv64" calling convention behaves the same as the
12+
// "C" calling convention on platforms where both should be the same
13+
14+
// This file contains versions of the following run-pass tests with
15+
// the calling convention changed to "sysv64"
16+
17+
// cabi-int-widening
18+
// extern-pass-char
19+
// extern-pass-u32
20+
// extern-pass-u64
21+
// extern-pass-double
22+
// extern-pass-empty
23+
// extern-pass-TwoU8s
24+
// extern-pass-TwoU16s
25+
// extern-pass-TwoU32s
26+
// extern-pass-TwoU64s
27+
// extern-return-TwoU8s
28+
// extern-return-TwoU16s
29+
// extern-return-TwoU32s
30+
// extern-return-TwoU64s
31+
// foreign-fn-with-byval
32+
// issue-28676
33+
// struct-return
34+
35+
// ignore-android
36+
// ignore-arm
37+
// ignore-aarch64
38+
// ignore-msvc
39+
40+
// note: msvc is ignored as rust_test_helpers does not have the sysv64 abi on msvc
41+
42+
#![feature(abi_sysv64)]
43+
#[allow(dead_code)]
44+
#[allow(improper_ctypes)]
45+
46+
#[cfg(target_arch = "x86_64")]
47+
mod tests {
48+
#[repr(C)]
49+
#[derive(Copy, Clone, PartialEq, Debug)]
50+
pub struct TwoU8s {
51+
one: u8, two: u8
52+
}
53+
54+
#[repr(C)]
55+
#[derive(Copy, Clone, PartialEq, Debug)]
56+
pub struct TwoU16s {
57+
one: u16, two: u16
58+
}
59+
60+
#[repr(C)]
61+
#[derive(Copy, Clone, PartialEq, Debug)]
62+
pub struct TwoU32s {
63+
one: u32, two: u32
64+
}
65+
66+
#[repr(C)]
67+
#[derive(Copy, Clone, PartialEq, Debug)]
68+
pub struct TwoU64s {
69+
one: u64, two: u64
70+
}
71+
72+
#[repr(C)]
73+
pub struct ManyInts {
74+
arg1: i8,
75+
arg2: i16,
76+
arg3: i32,
77+
arg4: i16,
78+
arg5: i8,
79+
arg6: TwoU8s,
80+
}
81+
82+
#[repr(C)]
83+
pub struct Empty;
84+
85+
#[repr(C)]
86+
#[derive(Copy, Clone)]
87+
pub struct S {
88+
x: u64,
89+
y: u64,
90+
z: u64,
91+
}
92+
93+
#[repr(C)]
94+
#[derive(Copy, Clone)]
95+
pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
96+
97+
#[repr(C)]
98+
#[derive(Copy, Clone)]
99+
pub struct Floats { a: f64, b: u8, c: f64 }
100+
101+
#[link(name = "rust_test_helpers")]
102+
extern "sysv64" {
103+
pub fn rust_int8_to_int32(_: i8) -> i32;
104+
pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
105+
pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
106+
pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
107+
pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
108+
pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
109+
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
110+
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
111+
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
112+
pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
113+
pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
114+
pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
115+
pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
116+
pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
117+
pub fn get_x(x: S) -> u64;
118+
pub fn get_y(x: S) -> u64;
119+
pub fn get_z(x: S) -> u64;
120+
pub fn get_c_many_params(_: *const (), _: *const (),
121+
_: *const (), _: *const (), f: Quad) -> u64;
122+
pub fn rust_dbg_abi_1(q: Quad) -> Quad;
123+
pub fn rust_dbg_abi_2(f: Floats) -> Floats;
124+
}
125+
126+
pub fn cabi_int_widening() {
127+
let x = unsafe {
128+
rust_int8_to_int32(-1)
129+
};
130+
131+
assert!(x == -1);
132+
}
133+
134+
pub fn extern_pass_char() {
135+
unsafe {
136+
assert_eq!(22, rust_dbg_extern_identity_u8(22));
137+
}
138+
}
139+
140+
pub fn extern_pass_u32() {
141+
unsafe {
142+
assert_eq!(22, rust_dbg_extern_identity_u32(22));
143+
}
144+
}
145+
146+
pub fn extern_pass_u64() {
147+
unsafe {
148+
assert_eq!(22, rust_dbg_extern_identity_u64(22));
149+
}
150+
}
151+
152+
pub fn extern_pass_double() {
153+
unsafe {
154+
assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
155+
}
156+
}
157+
158+
pub fn extern_pass_empty() {
159+
unsafe {
160+
let x = ManyInts {
161+
arg1: 2,
162+
arg2: 3,
163+
arg3: 4,
164+
arg4: 5,
165+
arg5: 6,
166+
arg6: TwoU8s { one: 7, two: 8, }
167+
};
168+
let y = ManyInts {
169+
arg1: 1,
170+
arg2: 2,
171+
arg3: 3,
172+
arg4: 4,
173+
arg5: 5,
174+
arg6: TwoU8s { one: 6, two: 7, }
175+
};
176+
let empty = Empty;
177+
rust_dbg_extern_empty_struct(x, empty, y);
178+
}
179+
}
180+
181+
pub fn extern_pass_twou8s() {
182+
unsafe {
183+
let x = TwoU8s {one: 22, two: 23};
184+
let y = rust_dbg_extern_identity_TwoU8s(x);
185+
assert_eq!(x, y);
186+
}
187+
}
188+
189+
pub fn extern_pass_twou16s() {
190+
unsafe {
191+
let x = TwoU16s {one: 22, two: 23};
192+
let y = rust_dbg_extern_identity_TwoU16s(x);
193+
assert_eq!(x, y);
194+
}
195+
}
196+
197+
pub fn extern_pass_twou32s() {
198+
unsafe {
199+
let x = TwoU32s {one: 22, two: 23};
200+
let y = rust_dbg_extern_identity_TwoU32s(x);
201+
assert_eq!(x, y);
202+
}
203+
}
204+
205+
pub fn extern_pass_twou64s() {
206+
unsafe {
207+
let x = TwoU64s {one: 22, two: 23};
208+
let y = rust_dbg_extern_identity_TwoU64s(x);
209+
assert_eq!(x, y);
210+
}
211+
}
212+
213+
pub fn extern_return_twou8s() {
214+
unsafe {
215+
let y = rust_dbg_extern_return_TwoU8s();
216+
assert_eq!(y.one, 10);
217+
assert_eq!(y.two, 20);
218+
}
219+
}
220+
221+
pub fn extern_return_twou16s() {
222+
unsafe {
223+
let y = rust_dbg_extern_return_TwoU16s();
224+
assert_eq!(y.one, 10);
225+
assert_eq!(y.two, 20);
226+
}
227+
}
228+
229+
pub fn extern_return_twou32s() {
230+
unsafe {
231+
let y = rust_dbg_extern_return_TwoU32s();
232+
assert_eq!(y.one, 10);
233+
assert_eq!(y.two, 20);
234+
}
235+
}
236+
237+
pub fn extern_return_twou64s() {
238+
unsafe {
239+
let y = rust_dbg_extern_return_TwoU64s();
240+
assert_eq!(y.one, 10);
241+
assert_eq!(y.two, 20);
242+
}
243+
}
244+
245+
#[inline(never)]
246+
fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 {
247+
unsafe {
248+
func(s)
249+
}
250+
}
251+
252+
pub fn foreign_fn_with_byval() {
253+
let s = S { x: 1, y: 2, z: 3 };
254+
assert_eq!(s.x, indirect_call(get_x, s));
255+
assert_eq!(s.y, indirect_call(get_y, s));
256+
assert_eq!(s.z, indirect_call(get_z, s));
257+
}
258+
259+
fn test() {
260+
use std::ptr;
261+
unsafe {
262+
let null = ptr::null();
263+
let q = Quad {
264+
a: 1,
265+
b: 2,
266+
c: 3,
267+
d: 4
268+
};
269+
assert_eq!(get_c_many_params(null, null, null, null, q), q.c);
270+
}
271+
}
272+
273+
pub fn issue_28676() {
274+
test();
275+
}
276+
277+
fn test1() {
278+
unsafe {
279+
let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
280+
b: 0xbbbb_bbbb_bbbb_bbbb,
281+
c: 0xcccc_cccc_cccc_cccc,
282+
d: 0xdddd_dddd_dddd_dddd };
283+
let qq = rust_dbg_abi_1(q);
284+
println!("a: {:x}", qq.a as usize);
285+
println!("b: {:x}", qq.b as usize);
286+
println!("c: {:x}", qq.c as usize);
287+
println!("d: {:x}", qq.d as usize);
288+
assert_eq!(qq.a, q.c + 1);
289+
assert_eq!(qq.b, q.d - 1);
290+
assert_eq!(qq.c, q.a + 1);
291+
assert_eq!(qq.d, q.b - 1);
292+
}
293+
}
294+
295+
fn test2() {
296+
unsafe {
297+
let f = Floats { a: 1.234567890e-15_f64,
298+
b: 0b_1010_1010,
299+
c: 1.0987654321e-15_f64 };
300+
let ff = rust_dbg_abi_2(f);
301+
println!("a: {}", ff.a as f64);
302+
println!("b: {}", ff.b as usize);
303+
println!("c: {}", ff.c as f64);
304+
assert_eq!(ff.a, f.c + 1.0f64);
305+
assert_eq!(ff.b, 0xff);
306+
assert_eq!(ff.c, f.a - 1.0f64);
307+
}
308+
}
309+
310+
pub fn struct_return() {
311+
test1();
312+
test2();
313+
}
314+
}
315+
316+
#[cfg(target_arch = "x86_64")]
317+
fn main() {
318+
use tests::*;
319+
cabi_int_widening();
320+
extern_pass_char();
321+
extern_pass_u32();
322+
extern_pass_u64();
323+
extern_pass_double();
324+
extern_pass_empty();
325+
extern_pass_twou8s();
326+
extern_pass_twou16s();
327+
extern_pass_twou32s();
328+
extern_pass_twou64s();
329+
extern_return_twou8s();
330+
extern_return_twou16s();
331+
extern_return_twou32s();
332+
extern_return_twou64s();
333+
foreign_fn_with_byval();
334+
issue_28676();
335+
struct_return();
336+
}
337+
338+
#[cfg(not(target_arch = "x86_64"))]
339+
fn main() {
340+
341+
}

0 commit comments

Comments
 (0)