From 4aef1011e64d6be56f6223151aaf6e694e5a49b0 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:08:03 +0100 Subject: [PATCH 1/3] Add `#[rustc_no_mir_inline]` for standard library UB checks --- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++++ compiler/rustc_mir_transform/src/inline.rs | 5 +++++ compiler/rustc_span/src/symbol.rs | 1 + library/core/src/intrinsics.rs | 2 +- 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 6aedd2a5e3341..0d5aa8a5d5eb5 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -788,6 +788,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing, "the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe" ), + rustc_attr!( + rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, + "#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen" + ), // ========================================================================== // Internal attributes, Testing: diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 956d855ab81a2..6521ba166b72b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::source_map::Spanned; +use rustc_span::sym; use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi; @@ -279,6 +280,10 @@ impl<'tcx> Inliner<'tcx> { } } + if self.tcx.has_attr(callsite.callee.def_id(), sym::rustc_no_mir_inline) { + return Err("found #[rustc_no_mir_inline] on callee"); + } + let old_blocks = caller_body.basic_blocks.next_index(); self.inline_call(caller_body, callsite, callee_body); let new_blocks = old_blocks..caller_body.basic_blocks.next_index(); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 134aa9efc01b6..c15f06c6214b0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1435,6 +1435,7 @@ symbols! { rustc_mir, rustc_must_implement_one_of, rustc_never_returns_null_ptr, + rustc_no_mir_inline, rustc_nonnull_optimization_guaranteed, rustc_nounwind, rustc_object_lifetime_default, diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index c8259c0024c75..59e79d6e398e0 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2640,7 +2640,7 @@ pub(crate) const fn debug_assertions() -> bool { macro_rules! assert_unsafe_precondition { ($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => { { - #[inline(never)] + #[cfg_attr(not(bootstrap), rustc_no_mir_inline)] #[rustc_nounwind] fn precondition_check($($name:$ty),*) { if !$e { From ffcbf96336f914711c9546008b3c334d31b547c4 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 14 Feb 2024 16:59:44 -0500 Subject: [PATCH 2/3] Check for rustc_no_mir_inline earlier --- compiler/rustc_mir_transform/src/inline.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 6521ba166b72b..f96b92f1c3c94 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -280,10 +280,6 @@ impl<'tcx> Inliner<'tcx> { } } - if self.tcx.has_attr(callsite.callee.def_id(), sym::rustc_no_mir_inline) { - return Err("found #[rustc_no_mir_inline] on callee"); - } - let old_blocks = caller_body.basic_blocks.next_index(); self.inline_call(caller_body, callsite, callee_body); let new_blocks = old_blocks..caller_body.basic_blocks.next_index(); @@ -418,6 +414,10 @@ impl<'tcx> Inliner<'tcx> { callee_attrs: &CodegenFnAttrs, cross_crate_inlinable: bool, ) -> Result<(), &'static str> { + if self.tcx.has_attr(callsite.callee.def_id(), sym::rustc_no_mir_inline) { + return Err("#[rustc_no_mir_inline]"); + } + if let InlineAttr::Never = callee_attrs.inline { return Err("never inline hint"); } From 749d7e25a760894e26d5a68f8e2a87aa06823e9a Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 14 Feb 2024 16:59:49 -0500 Subject: [PATCH 3/3] Enable backend inlining --- library/core/src/intrinsics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 59e79d6e398e0..51d488d898b3d 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2640,7 +2640,7 @@ pub(crate) const fn debug_assertions() -> bool { macro_rules! assert_unsafe_precondition { ($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => { { - #[cfg_attr(not(bootstrap), rustc_no_mir_inline)] + #[cfg_attr(not(bootstrap), rustc_no_mir_inline, inline)] #[rustc_nounwind] fn precondition_check($($name:$ty),*) { if !$e {