From 04c00585c36e6e74dbe998d7c3b190955f757469 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 16:12:43 +0000 Subject: [PATCH 1/2] Properly support thin ptrs that are only thin due to their param-env in asm macro --- compiler/rustc_hir_analysis/src/check/intrinsicck.rs | 6 ++---- compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 3 ++- tests/ui/asm/conditionally-sized-ptr.rs | 12 ++++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 tests/ui/asm/conditionally-sized-ptr.rs diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index e1727fc48a833..d62fa48bae316 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -33,14 +33,12 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { pub fn new( tcx: TyCtxt<'tcx>, def_id: LocalDefId, + typing_env: ty::TypingEnv<'tcx>, get_operand_ty: impl Fn(&hir::Expr<'tcx>) -> Ty<'tcx> + 'a, ) -> Self { InlineAsmCtxt { tcx, - typing_env: ty::TypingEnv { - typing_mode: ty::TypingMode::non_body_analysis(), - param_env: ty::ParamEnv::empty(), - }, + typing_env, target_features: tcx.asm_target_features(def_id), expr_ty: Box::new(get_operand_ty), } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index edd740d8d8f24..63c1c0608274a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -110,7 +110,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.erase_regions(ty) } }; - InlineAsmCtxt::new(self.tcx, enclosing_id, expr_ty).check_asm(asm); + InlineAsmCtxt::new(self.tcx, enclosing_id, self.typing_env(self.param_env), expr_ty) + .check_asm(asm); } } diff --git a/tests/ui/asm/conditionally-sized-ptr.rs b/tests/ui/asm/conditionally-sized-ptr.rs new file mode 100644 index 0000000000000..8ff18fd1da165 --- /dev/null +++ b/tests/ui/asm/conditionally-sized-ptr.rs @@ -0,0 +1,12 @@ +//@ check-pass +//@ needs-asm-support + +use std::arch::asm; + +fn _f(p: *mut T) { + unsafe { + asm!("/* {} */", in(reg) p); + } +} + +fn main() {} From b2dee4226d55f94048be1f5800df73c1430f36b1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 24 Feb 2025 16:20:50 +0000 Subject: [PATCH 2/2] Better error message for unsized pointers --- .../src/check/intrinsicck.rs | 19 ++++++++++++++++++- tests/ui/asm/conditionally-sized-ptr-fail.rs | 19 +++++++++++++++++++ .../asm/conditionally-sized-ptr-fail.stderr | 18 ++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/ui/asm/conditionally-sized-ptr-fail.rs create mode 100644 tests/ui/asm/conditionally-sized-ptr-fail.stderr diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index d62fa48bae316..511947404506c 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -27,6 +27,7 @@ enum NonAsmTypeReason<'tcx> { UnevaluatedSIMDArrayLength(DefId, ty::Const<'tcx>), Invalid(Ty<'tcx>), InvalidElement(DefId, Ty<'tcx>), + NotSizedPtr(Ty<'tcx>), } impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { @@ -81,7 +82,13 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Float(FloatTy::F64) => Ok(InlineAsmType::F64), ty::Float(FloatTy::F128) => Ok(InlineAsmType::F128), ty::FnPtr(..) => Ok(asm_ty_isize), - ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Ok(asm_ty_isize), + ty::RawPtr(elem_ty, _) => { + if self.is_thin_ptr_ty(elem_ty) { + Ok(asm_ty_isize) + } else { + Err(NonAsmTypeReason::NotSizedPtr(ty)) + } + } ty::Adt(adt, args) if adt.repr().simd() => { let fields = &adt.non_enum_variant().fields; let field = &fields[FieldIdx::ZERO]; @@ -187,6 +194,16 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { can be used as arguments for inline assembly", ).emit(); } + NonAsmTypeReason::NotSizedPtr(ty) => { + let msg = format!( + "cannot use value of unsized pointer type `{ty}` for inline assembly" + ); + self.tcx + .dcx() + .struct_span_err(expr.span, msg) + .with_note("only sized pointers can be used in inline assembly") + .emit(); + } NonAsmTypeReason::InvalidElement(did, ty) => { let msg = format!( "cannot use SIMD vector with element type `{ty}` for inline assembly" diff --git a/tests/ui/asm/conditionally-sized-ptr-fail.rs b/tests/ui/asm/conditionally-sized-ptr-fail.rs new file mode 100644 index 0000000000000..b0a93495ffafe --- /dev/null +++ b/tests/ui/asm/conditionally-sized-ptr-fail.rs @@ -0,0 +1,19 @@ +//@ needs-asm-support + +use std::arch::asm; + +fn _f(p: *mut T) { + unsafe { + asm!("/* {} */", in(reg) p); + //~^ ERROR cannot use value of unsized pointer type `*mut T` for inline assembly + } +} + +fn _g(p: *mut [u8]) { + unsafe { + asm!("/* {} */", in(reg) p); + //~^ ERROR cannot use value of unsized pointer type `*mut [u8]` for inline assembly + } +} + +fn main() {} diff --git a/tests/ui/asm/conditionally-sized-ptr-fail.stderr b/tests/ui/asm/conditionally-sized-ptr-fail.stderr new file mode 100644 index 0000000000000..b88f59f569c6c --- /dev/null +++ b/tests/ui/asm/conditionally-sized-ptr-fail.stderr @@ -0,0 +1,18 @@ +error: cannot use value of unsized pointer type `*mut T` for inline assembly + --> $DIR/conditionally-sized-ptr-fail.rs:7:34 + | +LL | asm!("/* {} */", in(reg) p); + | ^ + | + = note: only sized pointers can be used in inline assembly + +error: cannot use value of unsized pointer type `*mut [u8]` for inline assembly + --> $DIR/conditionally-sized-ptr-fail.rs:14:34 + | +LL | asm!("/* {} */", in(reg) p); + | ^ + | + = note: only sized pointers can be used in inline assembly + +error: aborting due to 2 previous errors +