Remove run-pass directory #62593

This commit is contained in:
Kevin Per 2019-08-15 17:07:38 +02:00
parent a90d0876d1
commit 4a8ff5bb7c
55 changed files with 0 additions and 1913 deletions

View file

@ -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() {
}

View file

@ -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() {}

View file

@ -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());
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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());
}
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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() { }

View file

@ -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
}
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}

View file

@ -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));
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}

View file

@ -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));
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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));
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -1,3 +0,0 @@
extern crate issue_25185_1;
pub use issue_25185_1::rust_dbg_extern_identity_u32;

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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!();
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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
}

View file

@ -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;);
}

View file

@ -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);
}
}

View file

@ -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"));
}
}

View file

@ -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");

View file

@ -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"));
}

View file

@ -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() }
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -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);
}
}