From bbde683a8e23afa3d8e345ec2047f0c2fad8792f Mon Sep 17 00:00:00 2001 From: tiif Date: Tue, 21 Jan 2025 08:08:58 +0000 Subject: [PATCH 1/2] impl Display for Conv --- .../rustc_const_eval/src/interpret/call.rs | 4 +-- compiler/rustc_target/src/callconv/mod.rs | 32 +++++++++++++++++++ src/tools/miri/src/helpers.rs | 3 +- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index e6a34193c9d69..653ef6f0c017b 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -351,8 +351,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { if caller_fn_abi.conv != callee_fn_abi.conv { throw_ub_custom!( fluent::const_eval_incompatible_calling_conventions, - callee_conv = format!("{:?}", callee_fn_abi.conv), - caller_conv = format!("{:?}", caller_fn_abi.conv), + callee_conv = format!("{}", callee_fn_abi.conv), + caller_conv = format!("{}", caller_fn_abi.conv), ) } diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 41b78d9121d6d..43546a870b1dc 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -1,3 +1,4 @@ +use std::fmt::Display; use std::str::FromStr; use std::{fmt, iter}; @@ -881,6 +882,37 @@ impl FromStr for Conv { } } +impl Display for Conv { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Conv::C => "C", + Conv::Rust => "Rust", + Conv::Cold => "Cold", + Conv::PreserveMost => "PreserveMost", + Conv::PreserveAll => "PreserveAll", + Conv::ArmAapcs => "ArmAapcs", + Conv::CCmseNonSecureCall => "CCmseNonSecureCall", + Conv::CCmseNonSecureEntry => "CCmseNonSecureEntry", + Conv::Msp430Intr => "Msp430Intr", + Conv::PtxKernel => "PtxKernel", + Conv::GpuKernel => "GpuKernel", + Conv::X86Fastcall => "X86Fastcall", + Conv::X86Intr => "X86Intr", + Conv::X86Stdcall => "X86Stdcall", + Conv::X86ThisCall => "X86ThisCall", + Conv::X86VectorCall => "X86VectorCall", + Conv::X86_64SysV => "X86_64SysV", + Conv::X86_64Win64 => "X86_64Win64", + Conv::AvrInterrupt => "AvrInterrupt", + Conv::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt", + Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine } => "RiscvInterrupt(machine)", + Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor } => { + "RiscvInterrupt(supervisor)" + } + }) + } +} + // Some types are used a lot. Make sure they don't unintentionally get bigger. #[cfg(target_pointer_width = "64")] mod size_asserts { diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index ca8dbdac125d0..f7ca98d1c78c1 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -920,8 +920,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { fn check_abi<'a>(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, exp_abi: Conv) -> InterpResult<'a, ()> { if fn_abi.conv != exp_abi { throw_ub_format!( - "calling a function with ABI {:?} using caller ABI {:?}", - exp_abi, + "calling a function with ABI {exp_abi} using caller ABI {}", fn_abi.conv ); } From 74d57a5b1be4f85f493fa51a6b7f8c1dce8bd932 Mon Sep 17 00:00:00 2001 From: tiif Date: Mon, 3 Feb 2025 13:50:39 +0000 Subject: [PATCH 2/2] Add test and change ub message wording --- src/tools/miri/src/helpers.rs | 8 ++++---- .../miri/tests/fail/shims/callconv_mismatch.rs | 11 +++++++++++ .../tests/fail/shims/callconv_mismatch.stderr | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/tools/miri/tests/fail/shims/callconv_mismatch.rs create mode 100644 src/tools/miri/tests/fail/shims/callconv_mismatch.stderr diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index f7ca98d1c78c1..14ff48ab6727d 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -916,11 +916,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { self.read_c_str_with_char_size(ptr, wchar_t.size, wchar_t.align.abi) } - /// Check that the ABI is what we expect. - fn check_abi<'a>(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, exp_abi: Conv) -> InterpResult<'a, ()> { + /// Check that the calling convention is what we expect. + fn check_callconv<'a>(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, exp_abi: Conv) -> InterpResult<'a, ()> { if fn_abi.conv != exp_abi { throw_ub_format!( - "calling a function with ABI {exp_abi} using caller ABI {}", + "calling a function with calling convention {exp_abi} using caller calling convention {}", fn_abi.conv ); } @@ -956,7 +956,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { exp_abi: Conv, link_name: Symbol, ) -> InterpResult<'tcx, ()> { - self.check_abi(abi, exp_abi)?; + self.check_callconv(abi, exp_abi)?; if let Some((body, instance)) = self.eval_context_mut().lookup_exported_symbol(link_name)? { // If compiler-builtins is providing the symbol, then don't treat it as a clash. // We'll use our built-in implementation in `emulate_foreign_item_inner` for increased diff --git a/src/tools/miri/tests/fail/shims/callconv_mismatch.rs b/src/tools/miri/tests/fail/shims/callconv_mismatch.rs new file mode 100644 index 0000000000000..2f9b89ae08d2b --- /dev/null +++ b/src/tools/miri/tests/fail/shims/callconv_mismatch.rs @@ -0,0 +1,11 @@ +extern "Rust" { + fn pipe(fds: *mut std::ffi::c_int) -> std::ffi::c_int; +} + +// Test the error for calling convention mismatch. +fn main() { + let mut fds = [-1, -1]; + let res = unsafe { pipe(fds.as_mut_ptr()) }; + //~^ ERROR: calling a function with calling convention C using caller calling convention Rust + assert_eq!(res, 0); +} \ No newline at end of file diff --git a/src/tools/miri/tests/fail/shims/callconv_mismatch.stderr b/src/tools/miri/tests/fail/shims/callconv_mismatch.stderr new file mode 100644 index 0000000000000..11b57de195391 --- /dev/null +++ b/src/tools/miri/tests/fail/shims/callconv_mismatch.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: calling a function with calling convention C using caller calling convention Rust + --> tests/fail/shims/callconv_mismatch.rs:LL:CC + | +LL | let res = unsafe { pipe(fds.as_mut_ptr()) }; + | ^^^^^^^^^^^^^^^^^^^^^^ calling a function with calling convention C using caller calling convention Rust + | + = 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 tests/fail/shims/callconv_mismatch.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error +