Remove run-pass
directory #62593
This commit is contained in:
parent
a90d0876d1
commit
4a8ff5bb7c
55 changed files with 0 additions and 1913 deletions
|
@ -1,366 +0,0 @@
|
|||
// Checks if the "sysv64" calling convention behaves the same as the
|
||||
// "C" calling convention on platforms where both should be the same
|
||||
|
||||
// This file contains versions of the following run-pass tests with
|
||||
// the calling convention changed to "sysv64"
|
||||
|
||||
// cabi-int-widening
|
||||
// extern-pass-char
|
||||
// extern-pass-u32
|
||||
// extern-pass-u64
|
||||
// extern-pass-double
|
||||
// extern-pass-empty
|
||||
// extern-pass-TwoU8s
|
||||
// extern-pass-TwoU16s
|
||||
// extern-pass-TwoU32s
|
||||
// extern-pass-TwoU64s
|
||||
// extern-return-TwoU8s
|
||||
// extern-return-TwoU16s
|
||||
// extern-return-TwoU32s
|
||||
// extern-return-TwoU64s
|
||||
// foreign-fn-with-byval
|
||||
// issue-28676
|
||||
// issue-62350-sysv-neg-reg-counts
|
||||
// struct-return
|
||||
|
||||
// ignore-android
|
||||
// ignore-arm
|
||||
// ignore-aarch64
|
||||
// ignore-windows
|
||||
|
||||
// note: windows is ignored as rust_test_helpers does not have the sysv64 abi on windows
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[allow(improper_ctypes)]
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod tests {
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU8s {
|
||||
one: u8, two: u8
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU16s {
|
||||
one: u16, two: u16
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU32s {
|
||||
one: u32, two: u32
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU64s {
|
||||
one: u64, two: u64
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ManyInts {
|
||||
arg1: i8,
|
||||
arg2: i16,
|
||||
arg3: i32,
|
||||
arg4: i16,
|
||||
arg5: i8,
|
||||
arg6: TwoU8s,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Empty;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct S {
|
||||
x: u64,
|
||||
y: u64,
|
||||
z: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[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 }
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern "sysv64" {
|
||||
pub fn rust_int8_to_int32(_: i8) -> i32;
|
||||
pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
|
||||
pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
|
||||
pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
|
||||
pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
|
||||
pub fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
|
||||
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
|
||||
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
|
||||
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
|
||||
pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
|
||||
pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
|
||||
pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
|
||||
pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
|
||||
pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
|
||||
pub fn get_x(x: S) -> u64;
|
||||
pub fn get_y(x: S) -> u64;
|
||||
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;
|
||||
}
|
||||
|
||||
pub fn cabi_int_widening() {
|
||||
let x = unsafe {
|
||||
rust_int8_to_int32(-1)
|
||||
};
|
||||
|
||||
assert!(x == -1);
|
||||
}
|
||||
|
||||
pub fn extern_pass_char() {
|
||||
unsafe {
|
||||
assert_eq!(22, rust_dbg_extern_identity_u8(22));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_u32() {
|
||||
unsafe {
|
||||
assert_eq!(22, rust_dbg_extern_identity_u32(22));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_u64() {
|
||||
unsafe {
|
||||
assert_eq!(22, rust_dbg_extern_identity_u64(22));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_double() {
|
||||
unsafe {
|
||||
assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_empty() {
|
||||
unsafe {
|
||||
let x = ManyInts {
|
||||
arg1: 2,
|
||||
arg2: 3,
|
||||
arg3: 4,
|
||||
arg4: 5,
|
||||
arg5: 6,
|
||||
arg6: TwoU8s { one: 7, two: 8, }
|
||||
};
|
||||
let y = ManyInts {
|
||||
arg1: 1,
|
||||
arg2: 2,
|
||||
arg3: 3,
|
||||
arg4: 4,
|
||||
arg5: 5,
|
||||
arg6: TwoU8s { one: 6, two: 7, }
|
||||
};
|
||||
let empty = Empty;
|
||||
rust_dbg_extern_empty_struct(x, empty, y);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_twou8s() {
|
||||
unsafe {
|
||||
let x = TwoU8s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU8s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_twou16s() {
|
||||
unsafe {
|
||||
let x = TwoU16s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU16s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_twou32s() {
|
||||
unsafe {
|
||||
let x = TwoU32s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU32s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_pass_twou64s() {
|
||||
unsafe {
|
||||
let x = TwoU64s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU64s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_return_twou8s() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU8s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_return_twou16s() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU16s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_return_twou32s() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU32s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extern_return_twou64s() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU64s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn indirect_call(func: unsafe extern "sysv64" fn(s: S) -> u64, s: S) -> u64 {
|
||||
unsafe {
|
||||
func(s)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foreign_fn_with_byval() {
|
||||
let s = S { x: 1, y: 2, z: 3 };
|
||||
assert_eq!(s.x, indirect_call(get_x, s));
|
||||
assert_eq!(s.y, indirect_call(get_y, s));
|
||||
assert_eq!(s.z, indirect_call(get_z, s));
|
||||
}
|
||||
|
||||
fn test() {
|
||||
use std::ptr;
|
||||
unsafe {
|
||||
let null = ptr::null();
|
||||
let q = Quad {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4
|
||||
};
|
||||
assert_eq!(get_c_many_params(null, null, null, null, q), q.c);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn issue_28676() {
|
||||
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,
|
||||
b: 0xbbbb_bbbb_bbbb_bbbb,
|
||||
c: 0xcccc_cccc_cccc_cccc,
|
||||
d: 0xdddd_dddd_dddd_dddd };
|
||||
let qq = rust_dbg_abi_1(q);
|
||||
println!("a: {:x}", qq.a as usize);
|
||||
println!("b: {:x}", qq.b as usize);
|
||||
println!("c: {:x}", qq.c as usize);
|
||||
println!("d: {:x}", qq.d as usize);
|
||||
assert_eq!(qq.a, q.c + 1);
|
||||
assert_eq!(qq.b, q.d - 1);
|
||||
assert_eq!(qq.c, q.a + 1);
|
||||
assert_eq!(qq.d, q.b - 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
unsafe {
|
||||
let f = Floats { a: 1.234567890e-15_f64,
|
||||
b: 0b_1010_1010,
|
||||
c: 1.0987654321e-15_f64 };
|
||||
let ff = rust_dbg_abi_2(f);
|
||||
println!("a: {}", ff.a as f64);
|
||||
println!("b: {}", ff.b as usize);
|
||||
println!("c: {}", ff.c as f64);
|
||||
assert_eq!(ff.a, f.c + 1.0f64);
|
||||
assert_eq!(ff.b, 0xff);
|
||||
assert_eq!(ff.c, f.a - 1.0f64);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_return() {
|
||||
test1();
|
||||
test2();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn main() {
|
||||
use tests::*;
|
||||
cabi_int_widening();
|
||||
extern_pass_char();
|
||||
extern_pass_u32();
|
||||
extern_pass_u64();
|
||||
extern_pass_double();
|
||||
extern_pass_empty();
|
||||
extern_pass_twou8s();
|
||||
extern_pass_twou16s();
|
||||
extern_pass_twou32s();
|
||||
extern_pass_twou64s();
|
||||
extern_return_twou8s();
|
||||
extern_return_twou16s();
|
||||
extern_return_twou32s();
|
||||
extern_return_twou64s();
|
||||
foreign_fn_with_byval();
|
||||
issue_28676();
|
||||
issue_62350();
|
||||
struct_return();
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
fn main() {
|
||||
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
// Checks if the correct registers are being used to pass arguments
|
||||
// when the sysv64 ABI is specified.
|
||||
|
||||
// ignore-android
|
||||
// ignore-arm
|
||||
// ignore-aarch64
|
||||
|
||||
#![feature(asm)]
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub extern "sysv64" fn all_the_registers(rdi: i64, rsi: i64, rdx: i64,
|
||||
rcx: i64, r8 : i64, r9 : i64,
|
||||
xmm0: f32, xmm1: f32, xmm2: f32,
|
||||
xmm3: f32, xmm4: f32, xmm5: f32,
|
||||
xmm6: f32, xmm7: f32) -> i64 {
|
||||
assert_eq!(rdi, 1);
|
||||
assert_eq!(rsi, 2);
|
||||
assert_eq!(rdx, 3);
|
||||
assert_eq!(rcx, 4);
|
||||
assert_eq!(r8, 5);
|
||||
assert_eq!(r9, 6);
|
||||
assert_eq!(xmm0, 1.0f32);
|
||||
assert_eq!(xmm1, 2.0f32);
|
||||
assert_eq!(xmm2, 4.0f32);
|
||||
assert_eq!(xmm3, 8.0f32);
|
||||
assert_eq!(xmm4, 16.0f32);
|
||||
assert_eq!(xmm5, 32.0f32);
|
||||
assert_eq!(xmm6, 64.0f32);
|
||||
assert_eq!(xmm7, 128.0f32);
|
||||
42
|
||||
}
|
||||
|
||||
// this struct contains 8 i64's, while only 6 can be passed in registers.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[derive(PartialEq, Eq, Debug)]
|
||||
pub struct LargeStruct(i64, i64, i64, i64, i64, i64, i64, i64);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
#[inline(never)]
|
||||
pub extern "sysv64" fn large_struct_by_val(mut foo: LargeStruct) -> LargeStruct {
|
||||
foo.0 *= 1;
|
||||
foo.1 *= 2;
|
||||
foo.2 *= 3;
|
||||
foo.3 *= 4;
|
||||
foo.4 *= 5;
|
||||
foo.5 *= 6;
|
||||
foo.6 *= 7;
|
||||
foo.7 *= 8;
|
||||
foo
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn main() {
|
||||
let result: i64;
|
||||
unsafe {
|
||||
asm!("mov rdi, 1;
|
||||
mov rsi, 2;
|
||||
mov rdx, 3;
|
||||
mov rcx, 4;
|
||||
mov r8, 5;
|
||||
mov r9, 6;
|
||||
mov eax, 0x3F800000;
|
||||
movd xmm0, eax;
|
||||
mov eax, 0x40000000;
|
||||
movd xmm1, eax;
|
||||
mov eax, 0x40800000;
|
||||
movd xmm2, eax;
|
||||
mov eax, 0x41000000;
|
||||
movd xmm3, eax;
|
||||
mov eax, 0x41800000;
|
||||
movd xmm4, eax;
|
||||
mov eax, 0x42000000;
|
||||
movd xmm5, eax;
|
||||
mov eax, 0x42800000;
|
||||
movd xmm6, eax;
|
||||
mov eax, 0x43000000;
|
||||
movd xmm7, eax;
|
||||
call r10
|
||||
"
|
||||
: "={rax}"(result)
|
||||
: "{r10}"(all_the_registers as usize)
|
||||
: "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11", "cc", "memory"
|
||||
: "intel", "alignstack"
|
||||
)
|
||||
}
|
||||
assert_eq!(result, 42);
|
||||
|
||||
assert_eq!(
|
||||
large_struct_by_val(LargeStruct(1, 2, 3, 4, 5, 6, 7, 8)),
|
||||
LargeStruct(1, 4, 9, 16, 25, 36, 49, 64)
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
pub fn main() {}
|
|
@ -1,36 +0,0 @@
|
|||
#![allow(unused_must_use)]
|
||||
// Since we mark some ABIs as "nounwind" to LLVM, we must make sure that
|
||||
// we never unwind through them.
|
||||
|
||||
// ignore-cloudabi no env and process
|
||||
// ignore-emscripten no processes
|
||||
// ignore-sgx no processes
|
||||
|
||||
use std::{env, panic};
|
||||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
extern "C" fn panic_in_ffi() {
|
||||
panic!("Test");
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let _ = panic::catch_unwind(|| { panic_in_ffi(); });
|
||||
// The process should have aborted by now.
|
||||
io::stdout().write(b"This should never be printed.\n");
|
||||
let _ = io::stdout().flush();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() > 1 && args[1] == "test" {
|
||||
return test();
|
||||
}
|
||||
|
||||
let mut p = Command::new(&args[0])
|
||||
.stdout(Stdio::piped())
|
||||
.stdin(Stdio::piped())
|
||||
.arg("test").spawn().unwrap();
|
||||
assert!(!p.wait().unwrap().success());
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// pretty-expanded FIXME #23616
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let _ = rust_get_test_int();
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#![crate_name="anonexternmod"]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#![crate_name="foreign_lib"]
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
pub mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod rustrt2 {
|
||||
extern crate libc;
|
||||
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod rustrt3 {
|
||||
// Different type, but same ABI (on all supported platforms).
|
||||
// Ensures that we don't ICE or trigger LLVM asserts when
|
||||
// importing the same symbol under different types.
|
||||
// See https://github.com/rust-lang/rust/issues/32740.
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> *const u8;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local_uses() {
|
||||
unsafe {
|
||||
let x = rustrt::rust_get_test_int();
|
||||
assert_eq!(x, rustrt2::rust_get_test_int());
|
||||
assert_eq!(x as *const _, rustrt3::rust_get_test_int());
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// pretty-expanded FIXME #23616
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let _foo = rustrt::rust_get_test_int;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_int8_to_int32(_: i8) -> i32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = unsafe {
|
||||
rust_int8_to_int32(-1)
|
||||
};
|
||||
|
||||
assert!(x == -1);
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#![crate_name="anonexternmod"]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// run-pass
|
||||
// aux-build:anon-extern-mod-cross-crate-1.rs
|
||||
// pretty-expanded FIXME #23616
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
extern crate anonexternmod;
|
||||
|
||||
use anonexternmod::rust_get_test_int;
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
rust_get_test_int();
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#![crate_name="anonexternmod"]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
// aux-build:anon-extern-mod-cross-crate-1.rs
|
||||
// aux-build:anon-extern-mod-cross-crate-1.rs
|
||||
// pretty-expanded FIXME #23616
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
extern crate anonexternmod;
|
||||
|
||||
pub fn main() { }
|
|
@ -1,31 +0,0 @@
|
|||
#![crate_name="externcallback"]
|
||||
#![crate_type = "lib"]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
pub mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
-> libc::uintptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
|
||||
unsafe {
|
||||
println!("n = {}", n);
|
||||
rustrt::rust_dbg_call(cb, n)
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
||||
if data == 1 {
|
||||
data
|
||||
} else {
|
||||
fact(data - 1) * data
|
||||
}
|
||||
}
|
39
src/test/run-pass/abi/extern/extern-call-deep.rs
vendored
39
src/test/run-pass/abi/extern/extern-call-deep.rs
vendored
|
@ -1,39 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
// ignore-emscripten blows the JS stack
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
-> libc::uintptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
||||
if data == 1 {
|
||||
data
|
||||
} else {
|
||||
count(data - 1) + 1
|
||||
}
|
||||
}
|
||||
|
||||
fn count(n: libc::uintptr_t) -> libc::uintptr_t {
|
||||
unsafe {
|
||||
println!("n = {}", n);
|
||||
rustrt::rust_dbg_call(cb, n)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let result = count(1000);
|
||||
println!("result = {}", result);
|
||||
assert_eq!(result, 1000);
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(unused_must_use)]
|
||||
// ignore-emscripten no threads support
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
use std::thread;
|
||||
|
||||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
-> libc::uintptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
||||
if data == 1 {
|
||||
data
|
||||
} else {
|
||||
count(data - 1) + 1
|
||||
}
|
||||
}
|
||||
|
||||
fn count(n: libc::uintptr_t) -> libc::uintptr_t {
|
||||
unsafe {
|
||||
println!("n = {}", n);
|
||||
rustrt::rust_dbg_call(cb, n)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// Make sure we're on a thread with small Rust stacks (main currently
|
||||
// has a large stack)
|
||||
thread::spawn(move|| {
|
||||
let result = count(1000);
|
||||
println!("result = {}", result);
|
||||
assert_eq!(result, 1000);
|
||||
}).join();
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
-> libc::uintptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
||||
if data == 1 {
|
||||
data
|
||||
} else {
|
||||
fact(data - 1) * data
|
||||
}
|
||||
}
|
||||
|
||||
fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
|
||||
unsafe {
|
||||
println!("n = {}", n);
|
||||
rustrt::rust_dbg_call(cb, n)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let result = fact(10);
|
||||
println!("result = {}", result);
|
||||
assert_eq!(result, 3628800);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(unused_must_use)]
|
||||
// This time we're testing repeatedly going up and down both stacks to
|
||||
// make sure the stack pointers are maintained properly in both
|
||||
// directions
|
||||
|
||||
// ignore-emscripten no threads support
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
use std::thread;
|
||||
|
||||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t) -> libc::uintptr_t,
|
||||
data: libc::uintptr_t)
|
||||
-> libc::uintptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
|
||||
if data == 1 {
|
||||
data
|
||||
} else {
|
||||
count(data - 1) + count(data - 1)
|
||||
}
|
||||
}
|
||||
|
||||
fn count(n: libc::uintptr_t) -> libc::uintptr_t {
|
||||
unsafe {
|
||||
println!("n = {}", n);
|
||||
rustrt::rust_dbg_call(cb, n)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// Make sure we're on a thread with small Rust stacks (main currently
|
||||
// has a large stack)
|
||||
thread::spawn(move|| {
|
||||
let result = count(12);
|
||||
println!("result = {}", result);
|
||||
assert_eq!(result, 2048);
|
||||
}).join();
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// run-pass
|
||||
// aux-build:extern-crosscrate-source.rs
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate externcallback;
|
||||
extern crate libc;
|
||||
|
||||
fn fact(n: libc::uintptr_t) -> libc::uintptr_t {
|
||||
unsafe {
|
||||
println!("n = {}", n);
|
||||
externcallback::rustrt::rust_dbg_call(externcallback::cb, n)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let result = fact(10);
|
||||
println!("result = {}", result);
|
||||
assert_eq!(result, 3628800);
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
// Test a foreign function that accepts and returns a struct
|
||||
// by value.
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU16s {
|
||||
one: u16, two: u16
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let x = TwoU16s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU16s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
// Test a foreign function that accepts and returns a struct
|
||||
// by value.
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU32s {
|
||||
one: u32, two: u32
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let x = TwoU32s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU32s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
// Test a foreign function that accepts and returns a struct
|
||||
// by value.
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU64s {
|
||||
one: u64, two: u64
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let x = TwoU64s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU64s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
// Test a foreign function that accepts and returns a struct
|
||||
// by value.
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub struct TwoU8s {
|
||||
one: u8, two: u8
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let x = TwoU8s {one: 22, two: 23};
|
||||
let y = rust_dbg_extern_identity_TwoU8s(x);
|
||||
assert_eq!(x, y);
|
||||
}
|
||||
}
|
16
src/test/run-pass/abi/extern/extern-pass-char.rs
vendored
16
src/test/run-pass/abi/extern/extern-pass-char.rs
vendored
|
@ -1,16 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
// Test a function that takes/returns a u8.
|
||||
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u8(v: u8) -> u8;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
assert_eq!(22, rust_dbg_extern_identity_u8(22));
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_double(v: f64) -> f64;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
assert_eq!(22.0_f64, rust_dbg_extern_identity_double(22.0_f64));
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)] // FIXME: this test is inherently not FFI-safe.
|
||||
|
||||
// Test a foreign function that accepts empty struct.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
// ignore-msvc
|
||||
// ignore-emscripten emcc asserts on an empty struct as an argument
|
||||
|
||||
#[repr(C)]
|
||||
struct TwoU8s {
|
||||
one: u8,
|
||||
two: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct ManyInts {
|
||||
arg1: i8,
|
||||
arg2: i16,
|
||||
arg3: i32,
|
||||
arg4: i16,
|
||||
arg5: i8,
|
||||
arg6: TwoU8s,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct Empty;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let x = ManyInts {
|
||||
arg1: 2,
|
||||
arg2: 3,
|
||||
arg3: 4,
|
||||
arg4: 5,
|
||||
arg5: 6,
|
||||
arg6: TwoU8s { one: 7, two: 8, }
|
||||
};
|
||||
let y = ManyInts {
|
||||
arg1: 1,
|
||||
arg2: 2,
|
||||
arg3: 3,
|
||||
arg4: 4,
|
||||
arg5: 5,
|
||||
arg6: TwoU8s { one: 6, two: 7, }
|
||||
};
|
||||
let empty = Empty;
|
||||
rust_dbg_extern_empty_struct(x, empty, y);
|
||||
}
|
||||
}
|
16
src/test/run-pass/abi/extern/extern-pass-u32.rs
vendored
16
src/test/run-pass/abi/extern/extern-pass-u32.rs
vendored
|
@ -1,16 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
// Test a function that takes/returns a u32.
|
||||
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u32(v: u32) -> u32;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
assert_eq!(22, rust_dbg_extern_identity_u32(22));
|
||||
}
|
||||
}
|
16
src/test/run-pass/abi/extern/extern-pass-u64.rs
vendored
16
src/test/run-pass/abi/extern/extern-pass-u64.rs
vendored
|
@ -1,16 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
// Test a call to a function that takes/returns a u64.
|
||||
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u64(v: u64) -> u64;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
assert_eq!(22, rust_dbg_extern_identity_u64(22));
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
pub struct TwoU16s {
|
||||
one: u16, two: u16
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU16s() -> TwoU16s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU16s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
pub struct TwoU32s {
|
||||
one: u32, two: u32
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU32s() -> TwoU32s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU32s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
pub struct TwoU64s {
|
||||
one: u64, two: u64
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU64s() -> TwoU64s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU64s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
pub struct TwoU8s {
|
||||
one: u8, two: u8
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_return_TwoU8s() -> TwoU8s;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let y = rust_dbg_extern_return_TwoU8s();
|
||||
assert_eq!(y.one, 10);
|
||||
assert_eq!(y.two, 20);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#![crate_name="foreign_lib"]
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
pub mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod rustrt2 {
|
||||
extern crate libc;
|
||||
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
pub mod rustrt3 {
|
||||
// Different type, but same ABI (on all supported platforms).
|
||||
// Ensures that we don't ICE or trigger LLVM asserts when
|
||||
// importing the same symbol under different types.
|
||||
// See https://github.com/rust-lang/rust/issues/32740.
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> *const u8;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local_uses() {
|
||||
unsafe {
|
||||
let x = rustrt::rust_get_test_int();
|
||||
assert_eq!(x, rustrt2::rust_get_test_int());
|
||||
assert_eq!(x as *const _, rustrt3::rust_get_test_int());
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-emscripten no threads support
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use std::mem;
|
||||
use std::thread;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
|
||||
data: libc::uintptr_t) -> libc::uintptr_t;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
thread::spawn(move|| {
|
||||
let i: isize = 100;
|
||||
rust_dbg_call(callback_isize, mem::transmute(&i));
|
||||
}).join().unwrap();
|
||||
|
||||
thread::spawn(move|| {
|
||||
let i: i32 = 100;
|
||||
rust_dbg_call(callback_i32, mem::transmute(&i));
|
||||
}).join().unwrap();
|
||||
|
||||
thread::spawn(move|| {
|
||||
let i: i64 = 100;
|
||||
rust_dbg_call(callback_i64, mem::transmute(&i));
|
||||
}).join().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
extern fn callback_isize(data: libc::uintptr_t) {
|
||||
unsafe {
|
||||
let data: *const isize = mem::transmute(data);
|
||||
assert_eq!(*data, 100);
|
||||
}
|
||||
}
|
||||
|
||||
extern fn callback_i64(data: libc::uintptr_t) {
|
||||
unsafe {
|
||||
let data: *const i64 = mem::transmute(data);
|
||||
assert_eq!(*data, 100);
|
||||
}
|
||||
}
|
||||
|
||||
extern fn callback_i32(data: libc::uintptr_t) {
|
||||
unsafe {
|
||||
let data: *const i32 = mem::transmute(data);
|
||||
assert_eq!(*data, 100);
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
// run-pass
|
||||
// aux-build:foreign_lib.rs
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
// Check that we can still call duplicated extern (imported) functions
|
||||
// which were declared in another crate. See issues #32740 and #32783.
|
||||
|
||||
|
||||
extern crate foreign_lib;
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let x = foreign_lib::rustrt::rust_get_test_int();
|
||||
assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int());
|
||||
assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int());
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct S {
|
||||
x: u64,
|
||||
y: u64,
|
||||
z: u64,
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn get_x(x: S) -> u64;
|
||||
pub fn get_y(x: S) -> u64;
|
||||
pub fn get_z(x: S) -> u64;
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
fn indirect_call(func: unsafe extern fn(s: S) -> u64, s: S) -> u64 {
|
||||
unsafe {
|
||||
func(s)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = S { x: 1, y: 2, z: 3 };
|
||||
assert_eq!(s.x, indirect_call(get_x, s));
|
||||
assert_eq!(s.y, indirect_call(get_y, s));
|
||||
assert_eq!(s.z, indirect_call(get_z, s));
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// run-pass
|
||||
// ABI is cdecl by default
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
mod rustrt {
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
rustrt::rust_get_test_int();
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// aux-build:foreign_lib.rs
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
// The purpose of this test is to check that we can
|
||||
// successfully (and safely) invoke external, cdecl
|
||||
// functions from outside the crate.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
extern crate foreign_lib;
|
||||
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let _foo = foreign_lib::rustrt::rust_get_test_int();
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_extern_identity_u32(u: u32) -> u32;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
extern crate issue_25185_1;
|
||||
|
||||
pub use issue_25185_1::rust_dbg_extern_identity_u32;
|
|
@ -1,13 +0,0 @@
|
|||
// run-pass
|
||||
// aux-build:issue-25185-1.rs
|
||||
// aux-build:issue-25185-2.rs
|
||||
// ignore-wasm32-bare no libc for ffi testing
|
||||
|
||||
extern crate issue_25185_2;
|
||||
|
||||
fn main() {
|
||||
let x = unsafe {
|
||||
issue_25185_2::rust_dbg_extern_identity_u32(1)
|
||||
};
|
||||
assert_eq!(x, 1);
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
|
||||
|
||||
mod rustrt {
|
||||
use super::Quad;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn get_c_many_params(_: *const (), _: *const (),
|
||||
_: *const (), _: *const (), f: Quad) -> u64;
|
||||
}
|
||||
}
|
||||
|
||||
fn test() {
|
||||
unsafe {
|
||||
let null = std::ptr::null();
|
||||
let q = Quad {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3,
|
||||
d: 4
|
||||
};
|
||||
assert_eq!(rustrt::get_c_many_params(null, null, null, null, q), q.c);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
test();
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
// dont-check-compiler-stderr (rust-lang/rust#54222)
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
// compile-flags: -lrust_test_helpers
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern "C" {
|
||||
pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
rust_dbg_extern_identity_u32(42);
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32
|
||||
|
||||
#![feature(decl_macro, macros_in_extern)]
|
||||
|
||||
macro_rules! returns_isize(
|
||||
($ident:ident) => (
|
||||
fn $ident() -> isize;
|
||||
)
|
||||
);
|
||||
|
||||
macro takes_u32_returns_u32($ident:ident) {
|
||||
fn $ident (arg: u32) -> u32;
|
||||
}
|
||||
|
||||
macro_rules! emits_nothing(
|
||||
() => ()
|
||||
);
|
||||
|
||||
fn main() {
|
||||
assert_eq!(unsafe { rust_get_test_int() }, 1isize);
|
||||
assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEFu32);
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
returns_isize!(rust_get_test_int);
|
||||
takes_u32_returns_u32!(rust_dbg_extern_identity_u32);
|
||||
emits_nothing!();
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_interesting_average(_: i64, ...) -> f64;
|
||||
}
|
||||
|
||||
fn test<T, U>(a: i64, b: i64, c: i64, d: i64, e: i64, f: T, g: U) -> i64 {
|
||||
unsafe {
|
||||
rust_interesting_average(6, a, a as f64,
|
||||
b, b as f64,
|
||||
c, c as f64,
|
||||
d, d as f64,
|
||||
e, e as f64,
|
||||
f, g) as i64
|
||||
}
|
||||
}
|
||||
|
||||
fn main(){
|
||||
assert_eq!(test(10, 20, 30, 40, 50, 60_i64, 60.0_f64), 70);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
// MSVC doesn't support 128 bit integers, and other Windows
|
||||
// C compilers have very inconsistent views on how the ABI
|
||||
// should look like.
|
||||
|
||||
// ignore-windows
|
||||
// ignore-32bit
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern "C" {
|
||||
fn identity(f: u128) -> u128;
|
||||
fn square(f: i128) -> i128;
|
||||
fn sub(f: i128, f: i128) -> i128;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let a = 0x734C_C2F2_A521;
|
||||
let b = 0x33EE_0E2A_54E2_59DA_A0E7_8E41;
|
||||
let b_out = identity(b);
|
||||
assert_eq!(b, b_out);
|
||||
let a_square = square(a);
|
||||
assert_eq!(b, a_square as u128);
|
||||
let k = 0x1234_5678_9ABC_DEFF_EDCB_A987_6543_210;
|
||||
let k_d = 0x2468_ACF1_3579_BDFF_DB97_530E_CA86_420;
|
||||
let k_out = sub(k_d, k);
|
||||
assert_eq!(k, k_out);
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
// force-host
|
||||
// no-prefer-dynamic
|
||||
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn nop_attr(_attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
assert!(_attr.to_string().is_empty());
|
||||
input
|
||||
}
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn no_output(_attr: TokenStream, _input: TokenStream) -> TokenStream {
|
||||
assert!(_attr.to_string().is_empty());
|
||||
assert!(!_input.to_string().is_empty());
|
||||
"".parse().unwrap()
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn emit_input(input: TokenStream) -> TokenStream {
|
||||
input
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// aux-build:test-macros.rs
|
||||
// ignore-wasm32
|
||||
|
||||
#![feature(macros_in_extern)]
|
||||
|
||||
extern crate test_macros;
|
||||
|
||||
use test_macros::{nop_attr, no_output, emit_input};
|
||||
|
||||
fn main() {
|
||||
assert_eq!(unsafe { rust_get_test_int() }, 1isize);
|
||||
assert_eq!(unsafe { rust_dbg_extern_identity_u32(0xDEADBEEF) }, 0xDEADBEEF);
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
#[no_output]
|
||||
fn some_definitely_unknown_symbol_which_should_be_removed();
|
||||
|
||||
#[nop_attr]
|
||||
fn rust_get_test_int() -> isize;
|
||||
|
||||
emit_input!(fn rust_dbg_extern_identity_u32(arg: u32) -> u32;);
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
// run-pass
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
// compile-flags: -lstatic=wronglibrary:rust_test_helpers
|
||||
|
||||
#[link(name = "wronglibrary", kind = "dylib")]
|
||||
extern "C" {
|
||||
pub fn rust_dbg_extern_identity_u32(x: u32) -> u32;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
rust_dbg_extern_identity_u32(42);
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
#![allow(unused_imports)]
|
||||
// ignore-cloudabi can't run commands
|
||||
// ignore-emscripten can't run commands
|
||||
// ignore-sgx no processes
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
use std::process::{Command, ExitStatus};
|
||||
use std::env;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_get_null_ptr() -> *mut ::libc::c_char;
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn check_status(status: std::process::ExitStatus)
|
||||
{
|
||||
use libc;
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
|
||||
assert!(status.signal() == Some(libc::SIGSEGV)
|
||||
|| status.signal() == Some(libc::SIGBUS));
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
fn check_status(status: std::process::ExitStatus)
|
||||
{
|
||||
assert!(!status.success());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() > 1 && args[1] == "segfault" {
|
||||
unsafe { *rust_get_null_ptr() = 1; }; // trigger a segfault
|
||||
} else {
|
||||
let segfault = Command::new(&args[0]).arg("segfault").output().unwrap();
|
||||
let stderr = String::from_utf8_lossy(&segfault.stderr);
|
||||
let stdout = String::from_utf8_lossy(&segfault.stdout);
|
||||
println!("stdout: {}", stdout);
|
||||
println!("stderr: {}", stderr);
|
||||
println!("status: {}", segfault.status);
|
||||
check_status(segfault.status);
|
||||
assert!(!stderr.contains("has overflowed its stack"));
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// ignore-arm
|
||||
// ignore-aarch64
|
||||
// ignore-mips
|
||||
// ignore-mips64
|
||||
// ignore-powerpc
|
||||
// ignore-s390x
|
||||
// ignore-sparc
|
||||
// ignore-sparc64
|
||||
// ignore-wasm
|
||||
// ignore-cloudabi no processes
|
||||
// ignore-emscripten no processes
|
||||
// ignore-sgx no processes
|
||||
// ignore-musl FIXME #31506
|
||||
// ignore-pretty
|
||||
// compile-flags: -C lto
|
||||
// no-prefer-dynamic
|
||||
|
||||
include!("stack-probes.rs");
|
|
@ -1,67 +0,0 @@
|
|||
// ignore-arm
|
||||
// ignore-aarch64
|
||||
// ignore-mips
|
||||
// ignore-mips64
|
||||
// ignore-powerpc
|
||||
// ignore-s390x
|
||||
// ignore-sparc
|
||||
// ignore-sparc64
|
||||
// ignore-wasm
|
||||
// ignore-cloudabi no processes
|
||||
// ignore-emscripten no processes
|
||||
// ignore-sgx no processes
|
||||
// ignore-musl FIXME #31506
|
||||
|
||||
use std::mem;
|
||||
use std::process::Command;
|
||||
use std::thread;
|
||||
use std::env;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
#[link_name = "rust_dbg_extern_identity_u64"]
|
||||
fn black_box(u: u64);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = env::args().skip(1).collect::<Vec<_>>();
|
||||
if args.len() > 0 {
|
||||
match &args[0][..] {
|
||||
"main-thread" => recurse(&[]),
|
||||
"child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(),
|
||||
_ => panic!(),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let me = env::current_exe().unwrap();
|
||||
|
||||
// The linux kernel has some different behavior for the main thread because
|
||||
// the main thread's stack can typically grow. We can't always guarantee
|
||||
// that we report stack overflow on the main thread, see #43052 for some
|
||||
// details
|
||||
if cfg!(not(target_os = "linux")) {
|
||||
assert_overflow(Command::new(&me).arg("main-thread"));
|
||||
}
|
||||
assert_overflow(Command::new(&me).arg("child-thread"));
|
||||
}
|
||||
|
||||
#[allow(unconditional_recursion)]
|
||||
fn recurse(array: &[u64]) {
|
||||
unsafe { black_box(array.as_ptr() as u64); }
|
||||
#[allow(deprecated)]
|
||||
let local: [_; 1024] = unsafe { mem::uninitialized() };
|
||||
recurse(&local);
|
||||
}
|
||||
|
||||
fn assert_overflow(cmd: &mut Command) {
|
||||
let output = cmd.output().unwrap();
|
||||
assert!(!output.status.success());
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||
println!("status: {}", output.status);
|
||||
println!("stdout: {}", stdout);
|
||||
println!("stderr: {}", stderr);
|
||||
assert!(stdout.is_empty());
|
||||
assert!(stderr.contains("has overflowed its stack\n"));
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
// run-pass
|
||||
// Constants (static variables) can be used to match in patterns, but mutable
|
||||
// statics cannot. This ensures that there's some form of error if this is
|
||||
// attempted.
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
static mut rust_dbg_static_mut: libc::c_int;
|
||||
pub fn rust_dbg_static_mut_check_four();
|
||||
}
|
||||
|
||||
unsafe fn static_bound(_: &'static libc::c_int) {}
|
||||
|
||||
fn static_bound_set(a: &'static mut libc::c_int) {
|
||||
*a = 3;
|
||||
}
|
||||
|
||||
unsafe fn run() {
|
||||
assert_eq!(rust_dbg_static_mut, 3);
|
||||
rust_dbg_static_mut = 4;
|
||||
assert_eq!(rust_dbg_static_mut, 4);
|
||||
rust_dbg_static_mut_check_four();
|
||||
rust_dbg_static_mut += 1;
|
||||
assert_eq!(rust_dbg_static_mut, 5);
|
||||
rust_dbg_static_mut *= 3;
|
||||
assert_eq!(rust_dbg_static_mut, 15);
|
||||
rust_dbg_static_mut = -3;
|
||||
assert_eq!(rust_dbg_static_mut, -3);
|
||||
static_bound(&rust_dbg_static_mut);
|
||||
static_bound_set(&mut rust_dbg_static_mut);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
unsafe { run() }
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct Floats { a: f64, b: u8, c: f64 }
|
||||
|
||||
mod rustrt {
|
||||
use super::{Floats, Quad};
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
pub fn rust_dbg_abi_1(q: Quad) -> Quad;
|
||||
pub fn rust_dbg_abi_2(f: Floats) -> Floats;
|
||||
}
|
||||
}
|
||||
|
||||
fn test1() {
|
||||
unsafe {
|
||||
let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
|
||||
b: 0xbbbb_bbbb_bbbb_bbbb,
|
||||
c: 0xcccc_cccc_cccc_cccc,
|
||||
d: 0xdddd_dddd_dddd_dddd };
|
||||
let qq = rustrt::rust_dbg_abi_1(q);
|
||||
println!("a: {:x}", qq.a as usize);
|
||||
println!("b: {:x}", qq.b as usize);
|
||||
println!("c: {:x}", qq.c as usize);
|
||||
println!("d: {:x}", qq.d as usize);
|
||||
assert_eq!(qq.a, q.c + 1);
|
||||
assert_eq!(qq.b, q.d - 1);
|
||||
assert_eq!(qq.c, q.a + 1);
|
||||
assert_eq!(qq.d, q.b - 1);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn test2() {
|
||||
unsafe {
|
||||
let f = Floats { a: 1.234567890e-15_f64,
|
||||
b: 0b_1010_1010,
|
||||
c: 1.0987654321e-15_f64 };
|
||||
let ff = rustrt::rust_dbg_abi_2(f);
|
||||
println!("a: {}", ff.a as f64);
|
||||
println!("b: {}", ff.b as usize);
|
||||
println!("c: {}", ff.c as f64);
|
||||
assert_eq!(ff.a, f.c + 1.0f64);
|
||||
assert_eq!(ff.b, 0xff);
|
||||
assert_eq!(ff.c, f.a - 1.0f64);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn test2() {
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
test1();
|
||||
test2();
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
// run-pass
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
// ignore-wasm32-bare no libc to test ffi with
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
struct LARGE_INTEGER_U {
|
||||
LowPart: u32,
|
||||
HighPart: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
union LARGE_INTEGER {
|
||||
__unnamed__: LARGE_INTEGER_U,
|
||||
u: LARGE_INTEGER_U,
|
||||
QuadPart: u64,
|
||||
}
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern "C" {
|
||||
fn increment_all_parts(_: LARGE_INTEGER) -> LARGE_INTEGER;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let mut li = LARGE_INTEGER { QuadPart: 0 };
|
||||
let li_c = increment_all_parts(li);
|
||||
li.__unnamed__.LowPart += 1;
|
||||
li.__unnamed__.HighPart += 1;
|
||||
li.u.LowPart += 1;
|
||||
li.u.HighPart += 1;
|
||||
li.QuadPart += 1;
|
||||
assert_eq!(li.QuadPart, li_c.QuadPart);
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
// ignore-wasm32-bare no libc to test ffi with
|
||||
#![feature(c_variadic)]
|
||||
|
||||
use std::ffi::VaList;
|
||||
|
||||
#[link(name = "rust_test_helpers", kind = "static")]
|
||||
extern {
|
||||
fn rust_interesting_average(_: u64, ...) -> f64;
|
||||
|
||||
// FIXME: we need to disable this lint for `VaList`,
|
||||
// since it contains a `MaybeUninit<i32>` on the asmjs target,
|
||||
// and this type isn't FFI-safe. This is OK for now,
|
||||
// since the type is layout-compatible with `i32`.
|
||||
#[cfg_attr(target_arch = "asmjs", allow(improper_ctypes))]
|
||||
fn rust_valist_interesting_average(_: u64, _: VaList) -> f64;
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn test_valist_forward(n: u64, mut ap: ...) -> f64 {
|
||||
rust_valist_interesting_average(n, ap.as_va_list())
|
||||
}
|
||||
|
||||
pub unsafe extern "C" fn test_va_copy(_: u64, mut ap: ...) {
|
||||
let mut ap2 = ap.clone();
|
||||
assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 30);
|
||||
|
||||
// Advance one pair in the copy before checking
|
||||
let mut ap2 = ap.clone();
|
||||
let _ = ap2.arg::<u64>();
|
||||
let _ = ap2.arg::<f64>();
|
||||
assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50);
|
||||
|
||||
// Advance one pair in the original
|
||||
let _ = ap.arg::<u64>();
|
||||
let _ = ap.arg::<f64>();
|
||||
|
||||
let mut ap2 = ap.clone();
|
||||
assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 50);
|
||||
|
||||
let mut ap2 = ap.clone();
|
||||
let _ = ap2.arg::<u64>();
|
||||
let _ = ap2.arg::<f64>();
|
||||
assert_eq!(rust_valist_interesting_average(2, ap2.as_va_list()) as i64, 70);
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
// Call without variadic arguments
|
||||
unsafe {
|
||||
assert!(rust_interesting_average(0).is_nan());
|
||||
}
|
||||
|
||||
// Call with direct arguments
|
||||
unsafe {
|
||||
assert_eq!(rust_interesting_average(1, 10i64, 10.0f64) as i64, 20);
|
||||
}
|
||||
|
||||
// Call with named arguments, variable number of them
|
||||
let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64);
|
||||
unsafe {
|
||||
assert_eq!(rust_interesting_average(2, x1, x2, x3, x4) as i64, 30);
|
||||
}
|
||||
|
||||
// A function that takes a function pointer
|
||||
unsafe fn call(fp: unsafe extern fn(u64, ...) -> f64) {
|
||||
let (x1, x2, x3, x4) = (10i64, 10.0f64, 20i64, 20.0f64);
|
||||
assert_eq!(fp(2, x1, x2, x3, x4) as i64, 30);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
call(rust_interesting_average);
|
||||
|
||||
// Make a function pointer, pass indirectly
|
||||
let x: unsafe extern fn(u64, ...) -> f64 = rust_interesting_average;
|
||||
call(x);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
assert_eq!(test_valist_forward(2, 10i64, 10f64, 20i64, 20f64) as i64, 30);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
test_va_copy(4, 10i64, 10f64, 20i64, 20f64, 30i64, 30f64, 40i64, 40f64);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue