diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index dd8d5ae624a3c..7dee2ed17b4be 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -22,7 +22,7 @@ pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'st } } -pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable"; +pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2"; pub enum AllocatorTy { Layout, diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 9cff8a84db3d9..ffb932a3c38e6 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -1,6 +1,7 @@ //! Allocator shim // Adapted from rustc +use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use rustc_ast::expand::allocator::{ ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, default_fn_name, global_fn_name, @@ -97,16 +98,31 @@ fn codegen_inner( data.define(Box::new([val])); module.define_data(data_id, &data).unwrap(); - let data_id = module - .declare_data( - &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), - Linkage::Export, - false, - false, - ) - .unwrap(); - let mut data = DataDescription::new(); - data.set_align(1); - data.define(Box::new([0])); - module.define_data(data_id, &data).unwrap(); + { + let sig = Signature { + call_conv: module.target_config().default_call_conv, + params: vec![], + returns: vec![], + }; + let func_id = module + .declare_function( + &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), + Linkage::Export, + &sig, + ) + .unwrap(); + + let mut ctx = Context::new(); + ctx.func.signature = sig; + let mut func_ctx = FunctionBuilderContext::new(); + let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); + + let block = bcx.create_block(); + bcx.switch_to_block(block); + bcx.ins().return_(&[]); + bcx.seal_all_blocks(); + bcx.finalize(); + + module.define_function(func_id, &mut ctx).unwrap(); + } } diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index f4ebd42ee2dc0..cf8aa500c778f 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -57,7 +57,7 @@ pub(crate) unsafe fn codegen( let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); - create_wrapper_function(tcx, context, &from_name, &to_name, &types, output); + create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output); } } @@ -66,7 +66,7 @@ pub(crate) unsafe fn codegen( tcx, context, &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), - &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), + Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), &[usize, usize], None, ); @@ -81,21 +81,21 @@ pub(crate) unsafe fn codegen( let value = context.new_rvalue_from_int(i8, value as i32); global.global_set_initializer_rvalue(value); - let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE); - let global = context.new_global(None, GlobalKind::Exported, i8, name); - #[cfg(feature = "master")] - global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( - tcx.sess.default_visibility(), - ))); - let value = context.new_rvalue_from_int(i8, 0); - global.global_set_initializer_rvalue(value); + create_wrapper_function( + tcx, + context, + &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), + None, + &[], + None, + ); } fn create_wrapper_function( tcx: TyCtxt<'_>, context: &Context<'_>, from_name: &str, - to_name: &str, + to_name: Option<&str>, types: &[Type<'_>], output: Option>, ) { @@ -124,34 +124,40 @@ fn create_wrapper_function( // TODO(antoyo): emit unwind tables. } - let args: Vec<_> = types - .iter() - .enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, format!("param{}", index))) - .collect(); - let callee = context.new_function( - None, - FunctionType::Extern, - output.unwrap_or(void), - &args, - to_name, - false, - ); - #[cfg(feature = "master")] - callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - let block = func.new_block("entry"); - let args = args - .iter() - .enumerate() - .map(|(i, _)| func.get_param(i as i32).to_rvalue()) - .collect::>(); - let ret = context.new_call(None, callee, &args); - //llvm::LLVMSetTailCall(ret, True); - if output.is_some() { - block.end_with_return(None, ret); + if let Some(to_name) = to_name { + let args: Vec<_> = types + .iter() + .enumerate() + .map(|(index, typ)| context.new_parameter(None, *typ, format!("param{}", index))) + .collect(); + let callee = context.new_function( + None, + FunctionType::Extern, + output.unwrap_or(void), + &args, + to_name, + false, + ); + #[cfg(feature = "master")] + callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); + + let args = args + .iter() + .enumerate() + .map(|(i, _)| func.get_param(i as i32).to_rvalue()) + .collect::>(); + let ret = context.new_call(None, callee, &args); + //llvm::LLVMSetTailCall(ret, True); + if output.is_some() { + block.end_with_return(None, ret); + } else { + block.add_eval(None, ret); + block.end_with_void_return(None); + } } else { + assert!(output.is_none()); block.end_with_void_return(None); } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 4a78e69497994..9dca63cfc8d4f 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -57,7 +57,7 @@ pub(crate) unsafe fn codegen( let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name)); let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name)); - create_wrapper_function(tcx, &cx, &from_name, &to_name, &args, output, false); + create_wrapper_function(tcx, &cx, &from_name, Some(&to_name), &args, output, false); } } @@ -66,7 +66,7 @@ pub(crate) unsafe fn codegen( tcx, &cx, &mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), - &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), + Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))), &[usize, usize], // size, align None, true, @@ -81,11 +81,16 @@ pub(crate) unsafe fn codegen( let llval = llvm::LLVMConstInt(i8, val as u64, False); llvm::set_initializer(ll_g, llval); - let name = mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE); - let ll_g = cx.declare_global(&name, i8); - llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility())); - let llval = llvm::LLVMConstInt(i8, 0, False); - llvm::set_initializer(ll_g, llval); + // __rust_no_alloc_shim_is_unstable_v2 + create_wrapper_function( + tcx, + &cx, + &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), + None, + &[], + None, + false, + ); } if tcx.sess.opts.debuginfo != DebugInfo::None { @@ -99,7 +104,7 @@ fn create_wrapper_function( tcx: TyCtxt<'_>, cx: &SimpleCx<'_>, from_name: &str, - to_name: &str, + to_name: Option<&str>, args: &[&Type], output: Option<&Type>, no_return: bool, @@ -128,33 +133,38 @@ fn create_wrapper_function( attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); } - let callee = declare_simple_fn( - &cx, - to_name, - llvm::CallConv::CCallConv, - llvm::UnnamedAddr::Global, - llvm::Visibility::Hidden, - ty, - ); - if let Some(no_return) = no_return { - // -> ! DIFlagNoReturn - attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]); - } - llvm::set_visibility(callee, llvm::Visibility::Hidden); - let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) }; - let mut bx = SBuilder::build(&cx, llbb); - let args = args - .iter() - .enumerate() - .map(|(i, _)| llvm::get_param(llfn, i as c_uint)) - .collect::>(); - let ret = bx.call(ty, callee, &args, None); - llvm::LLVMSetTailCall(ret, True); - if output.is_some() { - bx.ret(ret); + + if let Some(to_name) = to_name { + let callee = declare_simple_fn( + &cx, + to_name, + llvm::CallConv::CCallConv, + llvm::UnnamedAddr::Global, + llvm::Visibility::Hidden, + ty, + ); + if let Some(no_return) = no_return { + // -> ! DIFlagNoReturn + attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]); + } + llvm::set_visibility(callee, llvm::Visibility::Hidden); + + let args = args + .iter() + .enumerate() + .map(|(i, _)| llvm::get_param(llfn, i as c_uint)) + .collect::>(); + let ret = bx.call(ty, callee, &args, None); + llvm::LLVMSetTailCall(ret, True); + if output.is_some() { + bx.ret(ret); + } else { + bx.ret_void() + } } else { + assert!(output.is_none()); bx.ret_void() } } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 96aec9769d2ca..11623f4736d96 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -219,6 +219,7 @@ fn exported_symbols_provider_local<'tcx>( .chain([ mangle_internal_symbol(tcx, "__rust_alloc_error_handler"), mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), ]) { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); @@ -232,19 +233,6 @@ fn exported_symbols_provider_local<'tcx>( }, )); } - - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new( - tcx, - &mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE), - )); - symbols.push(( - exported_symbol, - SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Data, - used: false, - }, - )) } if tcx.sess.instrument_coverage() || tcx.sess.opts.cg.profile_generate.enabled() { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 4a99ce09b39ab..1e6d45ff558d6 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -85,10 +85,10 @@ pub fn mangle_internal_symbol<'tcx>(tcx: TyCtxt<'tcx>, item_name: &str) -> Strin if item_name == "rust_eh_personality" { // rust_eh_personality must not be renamed as LLVM hard-codes the name return "rust_eh_personality".to_owned(); - } else if item_name == "__rust_no_alloc_shim_is_unstable" { + } else if item_name == "__rust_no_alloc_shim_is_unstable_v2" { // Temporary back compat hack to give people the chance to migrate to // include #[rustc_std_internal_symbol]. - return "__rust_no_alloc_shim_is_unstable".to_owned(); + return "__rust_no_alloc_shim_is_unstable_v2".to_owned(); } let prefix = "_R"; diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index e1cc4ba25c4ea..723a4851b5d49 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -31,8 +31,14 @@ unsafe extern "Rust" { #[rustc_std_internal_symbol] fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; + #[rustc_nounwind] + #[rustc_std_internal_symbol] + #[cfg(not(bootstrap))] + fn __rust_no_alloc_shim_is_unstable_v2(); #[rustc_std_internal_symbol] + #[cfg(bootstrap)] static __rust_no_alloc_shim_is_unstable: u8; + } /// The global memory allocator. @@ -88,7 +94,10 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { unsafe { // Make sure we don't accidentally allow omitting the allocator shim in // stable code until it is actually stabilized. + #[cfg(bootstrap)] core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable); + #[cfg(not(bootstrap))] + __rust_no_alloc_shim_is_unstable_v2(); __rust_alloc(layout.size(), layout.align()) } @@ -171,7 +180,10 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { unsafe { // Make sure we don't accidentally allow omitting the allocator shim in // stable code until it is actually stabilized. + #[cfg(bootstrap)] core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable); + #[cfg(not(bootstrap))] + __rust_no_alloc_shim_is_unstable_v2(); __rust_alloc_zeroed(layout.size(), layout.align()) } diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index 2feed5a835228..a2ea3dbd88b11 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -45,10 +45,6 @@ impl<'tcx> MiriMachine<'tcx> { /// Sets up the "extern statics" for this machine. pub fn init_extern_statics(ecx: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> { - // "__rust_no_alloc_shim_is_unstable" - let val = ImmTy::from_int(0, ecx.machine.layouts.u8); // always 0, value does not matter - Self::alloc_extern_static(ecx, "__rust_no_alloc_shim_is_unstable", val)?; - // "__rust_alloc_error_handler_should_panic" let val = ecx.tcx.sess.opts.unstable_opts.oom.should_panic(); let val = ImmTy::from_int(val, ecx.machine.layouts.u8); diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 52c16a0c2e2dc..4cd28b874688f 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -607,6 +607,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { this.write_pointer(new_ptr, dest) }); } + "__rust_no_alloc_shim_is_unstable_v2" => { + // This is a no-op shim that only exists to prevent making the allocator shims instantly stable. + let [] = this.check_shim(abi, Conv::Rust, link_name, args)?; + } // C memory handling functions "memcmp" => { diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.rs b/src/tools/miri/tests/pass/alloc-access-tracking.rs index c47063bef03c7..0e88951dc43f9 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.rs +++ b/src/tools/miri/tests/pass/alloc-access-tracking.rs @@ -1,7 +1,7 @@ #![no_std] #![no_main] -//@compile-flags: -Zmiri-track-alloc-id=21 -Zmiri-track-alloc-accesses -Cpanic=abort -//@normalize-stderr-test: "id 21" -> "id $$ALLOC" +//@compile-flags: -Zmiri-track-alloc-id=20 -Zmiri-track-alloc-accesses -Cpanic=abort +//@normalize-stderr-test: "id 20" -> "id $$ALLOC" //@only-target: linux # alloc IDs differ between OSes (due to extern static allocations) extern "Rust" { diff --git a/tests/codegen/alloc-optimisation.rs b/tests/codegen/alloc-optimisation.rs index 19f14647c1d7d..e5d7e5f88708e 100644 --- a/tests/codegen/alloc-optimisation.rs +++ b/tests/codegen/alloc-optimisation.rs @@ -5,7 +5,7 @@ pub fn alloc_test(data: u32) { // CHECK-LABEL: @alloc_test // CHECK-NEXT: start: - // CHECK-NEXT: {{.*}} load volatile i8, ptr @{{.*}}__rust_no_alloc_shim_is_unstable, align 1 + // CHECK-NEXT: tail call void @__rust_no_alloc_shim_is_unstable_v2() // CHECK-NEXT: ret void let x = Box::new(data); drop(x); diff --git a/tests/codegen/unwind-landingpad-inline.rs b/tests/codegen/unwind-landingpad-inline.rs index 920774b340240..78a593491b971 100644 --- a/tests/codegen/unwind-landingpad-inline.rs +++ b/tests/codegen/unwind-landingpad-inline.rs @@ -10,8 +10,8 @@ // See https://github.com/rust-lang/rust/issues/46515 // CHECK-LABEL: @check_no_escape_in_landingpad // CHECK: start: -// CHECK-NEXT: __rust_no_alloc_shim_is_unstable -// CHECK-NEXT: __rust_no_alloc_shim_is_unstable +// CHECK-NEXT: tail call void @__rust_no_alloc_shim_is_unstable_v2() +// CHECK-NEXT: tail call void @__rust_no_alloc_shim_is_unstable_v2() // CHECK-NEXT: ret void #[no_mangle] pub fn check_no_escape_in_landingpad(f: fn()) { diff --git a/tests/codegen/vec-iter-collect-len.rs b/tests/codegen/vec-iter-collect-len.rs index a88573522d4d8..48828e95e0dd4 100644 --- a/tests/codegen/vec-iter-collect-len.rs +++ b/tests/codegen/vec-iter-collect-len.rs @@ -4,7 +4,8 @@ #[no_mangle] pub fn get_len() -> usize { // CHECK-LABEL: @get_len - // CHECK-NOT: call - // CHECK-NOT: invoke + // CHECK-NEXT: start: + // CHECK-NEXT: tail call void @__rust_no_alloc_shim_is_unstable_v2() + // CHECK-NEXT: ret i{{[0-9]+}} 3 [1, 2, 3].iter().collect::>().len() } diff --git a/tests/codegen/vec-optimizes-away.rs b/tests/codegen/vec-optimizes-away.rs index f6ed2898bdaaa..4ce8257b8dff1 100644 --- a/tests/codegen/vec-optimizes-away.rs +++ b/tests/codegen/vec-optimizes-away.rs @@ -5,7 +5,7 @@ pub fn sum_me() -> i32 { // CHECK-LABEL: @sum_me // CHECK-NEXT: {{^.*:$}} - // CHECK-NEXT: {{.*}} load volatile i8, ptr @{{.*}}__rust_no_alloc_shim_is_unstable, align 1 + // CHECK-NEXT: tail call void @__rust_no_alloc_shim_is_unstable_v2() // CHECK-NEXT: ret i32 6 vec![1, 2, 3].iter().sum::() } diff --git a/tests/run-make/no-alloc-shim/foo.rs b/tests/run-make/no-alloc-shim/foo.rs index 42606961f8bb2..641396bb8c11a 100644 --- a/tests/run-make/no-alloc-shim/foo.rs +++ b/tests/run-make/no-alloc-shim/foo.rs @@ -32,7 +32,7 @@ unsafe impl GlobalAlloc for Alloc { #[cfg(not(check_feature_gate))] #[no_mangle] -static __rust_no_alloc_shim_is_unstable: u8 = 0; +fn __rust_no_alloc_shim_is_unstable_v2() {} #[no_mangle] extern "C" fn main(_argc: core::ffi::c_int, _argv: *const *const i8) -> i32 { diff --git a/tests/run-make/no-alloc-shim/rmake.rs b/tests/run-make/no-alloc-shim/rmake.rs index d61ef5de8c56c..47cabfc208c77 100644 --- a/tests/run-make/no-alloc-shim/rmake.rs +++ b/tests/run-make/no-alloc-shim/rmake.rs @@ -7,12 +7,6 @@ //@ ignore-cross-compile // Reason: the compiled binary is executed -//@ ignore-msvc -//FIXME(Oneirical): Getting this to work on MSVC requires passing libcmt.lib to CC, -// which is not trivial to do. -// Tracking issue: https://github.com/rust-lang/rust/issues/128602 -// Discussion: https://github.com/rust-lang/rust/pull/128407#discussion_r1702439172 - use run_make_support::{cc, has_extension, has_prefix, run, rustc, shallow_find_files}; fn main() { @@ -30,15 +24,28 @@ fn main() { has_prefix(path, "libcompiler_builtins") && has_extension(path, "rlib") }); + #[allow(unused_mut)] + let mut platform_args = Vec::::new(); + #[cfg(target_env = "msvc")] + { + platform_args.push("-MD".to_string()); + + // `/link` tells MSVC that the remaining arguments are linker options. + platform_args.push("/link".to_string()); + platform_args.push("vcruntime.lib".to_string()); + platform_args.push("msvcrt.lib".to_string()); + } + cc().input("foo.o") .out_exe("foo") + .args(&platform_args) .args(&alloc_libs) .args(&core_libs) .args(&compiler_builtins_libs) .run(); run("foo"); - // Check that linking without __rust_no_alloc_shim_is_unstable defined fails + // Check that linking without __rust_no_alloc_shim_is_unstable_v2 defined fails rustc() .input("foo.rs") .crate_type("bin") @@ -48,6 +55,7 @@ fn main() { .run(); cc().input("foo.o") .out_exe("foo") + .args(&platform_args) .args(&alloc_libs) .args(&core_libs) .args(&compiler_builtins_libs) diff --git a/tests/run-make/symbols-all-mangled/rmake.rs b/tests/run-make/symbols-all-mangled/rmake.rs index 79ddd06bb94be..85c80b980fb99 100644 --- a/tests/run-make/symbols-all-mangled/rmake.rs +++ b/tests/run-make/symbols-all-mangled/rmake.rs @@ -35,7 +35,7 @@ fn symbols_check_archive(path: &str) { continue; // All compiler-builtins symbols must remain unmangled } - if name == "__rust_no_alloc_shim_is_unstable" { + if name == "__rust_no_alloc_shim_is_unstable_v2" { continue; // FIXME remove exception once we mangle this symbol } @@ -75,7 +75,7 @@ fn symbols_check(path: &str) { continue; } - if name == "__rust_no_alloc_shim_is_unstable" { + if name == "__rust_no_alloc_shim_is_unstable_v2" { continue; // FIXME remove exception once we mangle this symbol }