about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2023-08-30 12:26:17 +0200
committerRalf Jung <post@ralfj.de>2023-08-30 17:07:25 +0200
commitc37bd09d88fb720eb5172a833fea2d74a3d14b9a (patch)
tree1f8c4b713e7b6df7597c2c35dda062693e53ef99 /src
parentc1a34729e1a9e35af053c1c7ac76de6f2de3dfaf (diff)
downloadrust-c37bd09d88fb720eb5172a833fea2d74a3d14b9a.tar.gz
rust-c37bd09d88fb720eb5172a833fea2d74a3d14b9a.zip
miri function ABI check: specifically look for repr(transparent)
Diffstat (limited to 'src')
-rw-r--r--src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs16
-rw-r--r--src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr15
-rw-r--r--src/tools/miri/tests/pass/function_calls/abi_compat.rs4
3 files changed, 35 insertions, 0 deletions
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs
new file mode 100644
index 00000000000..415e91b250f
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.rs
@@ -0,0 +1,16 @@
+#![feature(portable_simd)]
+
+// Some targets treat arrays and structs very differently. We would probably catch that on those
+// targets since we check the `PassMode`; here we ensure that we catch it on *all* targets
+// (in particular, on x86-64 the pass mode is `Indirect` for both of these).
+struct S(i32, i32, i32, i32);
+type A = [i32; 4];
+
+fn main() {
+    fn f(_: S) {}
+
+    // These two types have the same size but are still not compatible.
+    let g = unsafe { std::mem::transmute::<fn(S), fn(A)>(f) };
+
+    g(Default::default()) //~ ERROR: calling a function with argument of type S passing data of type [i32; 4]
+}
diff --git a/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr
new file mode 100644
index 00000000000..50d4228c111
--- /dev/null
+++ b/src/tools/miri/tests/fail/function_pointers/abi_mismatch_array_vs_struct.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: calling a function with argument of type S passing data of type [i32; 4]
+  --> $DIR/abi_mismatch_array_vs_struct.rs:LL:CC
+   |
+LL |     g(Default::default())
+   |     ^^^^^^^^^^^^^^^^^^^^^ calling a function with argument of type S passing data of type [i32; 4]
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/abi_mismatch_array_vs_struct.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/pass/function_calls/abi_compat.rs b/src/tools/miri/tests/pass/function_calls/abi_compat.rs
index 1be29992f25..0786450f751 100644
--- a/src/tools/miri/tests/pass/function_calls/abi_compat.rs
+++ b/src/tools/miri/tests/pass/function_calls/abi_compat.rs
@@ -24,10 +24,13 @@ fn test_abi_newtype<T: Copy>(t: T) {
     #[repr(transparent)]
     struct Wrapper2<T>(T, ());
     #[repr(transparent)]
+    struct Wrapper2a<T>((), T);
+    #[repr(transparent)]
     struct Wrapper3<T>(T, [u8; 0]);
 
     test_abi_compat(t, Wrapper1(t));
     test_abi_compat(t, Wrapper2(t, ()));
+    test_abi_compat(t, Wrapper2a((), t));
     test_abi_compat(t, Wrapper3(t, []));
 }
 
@@ -46,4 +49,5 @@ fn main() {
     test_abi_newtype(0f32);
     test_abi_newtype((0u32, 1u32, 2u32));
     test_abi_newtype([0u32, 1u32, 2u32]);
+    test_abi_newtype([0i32; 0]);
 }