Skip to content

Commit 784f545

Browse files
committed
interpret: change ABI-compat test to be type-based, so the test is consistent across targets
1 parent f02302f commit 784f545

File tree

1 file changed

+21
-18
lines changed

1 file changed

+21
-18
lines changed

tests/pass/function_calls/abi_compat.rs

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use std::mem;
22
use std::num;
3+
use std::ptr;
34

45
#[derive(Copy, Clone, Default)]
56
struct Zst;
67

7-
fn test_abi_compat<T: Copy, U: Copy>(t: T, u: U) {
8+
fn test_abi_compat<T: Clone, U: Clone>(t: T, u: U) {
89
fn id<T>(x: T) -> T {
910
x
1011
}
@@ -16,10 +17,10 @@ fn test_abi_compat<T: Copy, U: Copy>(t: T, u: U) {
1617
// in both directions.
1718
let f: fn(T) -> T = id;
1819
let f: fn(U) -> U = unsafe { std::mem::transmute(f) };
19-
let _val = f(u);
20+
let _val = f(u.clone());
2021
let f: fn(U) -> U = id;
2122
let f: fn(T) -> T = unsafe { std::mem::transmute(f) };
22-
let _val = f(t);
23+
let _val = f(t.clone());
2324

2425
// And then we do the same for `extern "C"`.
2526
let f: extern "C" fn(T) -> T = id_c;
@@ -54,23 +55,25 @@ fn test_abi_newtype<T: Copy + Default>() {
5455
}
5556

5657
fn main() {
57-
// Here we check:
58-
// - u32 vs char is allowed
59-
// - u32 vs NonZeroU32/Option<NonZeroU32> is allowed
60-
// - reference vs raw pointer is allowed
61-
// - references to things of the same size and alignment are allowed
62-
// These are very basic tests that should work on all ABIs. However it is not clear that any of
63-
// these would be stably guaranteed. Code that relies on this is equivalent to code that relies
64-
// on the layout of `repr(Rust)` types. They are also fragile: the same mismatches in the fields
65-
// of a struct (even with `repr(C)`) will not always be accepted by Miri.
66-
// Note that `bool` and `u8` are *not* compatible, at least on x86-64!
67-
// One of them has `arg_ext: Zext`, the other does not.
68-
// Similarly, `i32` and `u32` are not compatible on s390x due to different `arg_ext`.
69-
test_abi_compat(0u32, 'x');
70-
test_abi_compat(42u32, num::NonZeroU32::new(1).unwrap());
71-
test_abi_compat(0u32, Some(num::NonZeroU32::new(1).unwrap()));
58+
// Here we check some of the guaranteed ABI compatibilities.
59+
// Different integer types of the same size and sign.
60+
if cfg!(target_pointer_width = "32") {
61+
test_abi_compat(0usize, 0u32);
62+
test_abi_compat(0isize, 0i32);
63+
} else {
64+
test_abi_compat(0usize, 0u64);
65+
test_abi_compat(0isize, 0i64);
66+
}
67+
// Reference/pointer types with the same pointee.
7268
test_abi_compat(&0u32, &0u32 as *const u32);
69+
test_abi_compat(&mut 0u32 as *mut u32, Box::new(0u32));
70+
test_abi_compat(&(), ptr::NonNull::<()>::dangling());
71+
// Reference/pointer types with different but sized pointees.
7372
test_abi_compat(&0u32, &([true; 4], [0u32; 0]));
73+
// Guaranteed null-pointer-optimizations.
74+
test_abi_compat(&0u32 as *const u32, Some(&0u32));
75+
test_abi_compat(42u32, num::NonZeroU32::new(1).unwrap());
76+
test_abi_compat(0u32, Some(num::NonZeroU32::new(1).unwrap()));
7477

7578
// These must work for *any* type, since we guarantee that `repr(transparent)` is ABI-compatible
7679
// with the wrapped field.

0 commit comments

Comments
 (0)