From 37f25feef429af4b9e3b96aae7a428275ad02c61 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:09:50 +0000 Subject: [PATCH 1/8] [WIP] Use weak linkage instead of compiler generated shims This is still keeping the allocator shim for the oom handler and the __rust_no_alloc_shim_is_unstable symbol for now. TODO: Update comments everywhere and test on macOS and Windows --- compiler/rustc_ast/src/expand/allocator.rs | 4 - .../rustc_codegen_cranelift/src/allocator.rs | 62 ++------ compiler/rustc_codegen_gcc/src/allocator.rs | 35 +---- compiler/rustc_codegen_gcc/src/lib.rs | 3 +- compiler/rustc_codegen_llvm/src/allocator.rs | 36 +---- compiler/rustc_codegen_llvm/src/lib.rs | 3 +- .../src/back/symbol_export.rs | 4 +- compiler/rustc_codegen_ssa/src/base.rs | 9 +- .../rustc_codegen_ssa/src/traits/backend.rs | 1 - compiler/rustc_metadata/src/creader.rs | 2 + .../rustc_monomorphize/src/partitioning.rs | 1 + library/alloc/src/alloc.rs | 2 +- library/std/src/alloc.rs | 17 ++- src/tools/miri/src/shims/alloc.rs | 33 +---- src/tools/miri/src/shims/foreign_items.rs | 140 ++++++++---------- 15 files changed, 107 insertions(+), 245 deletions(-) diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index dd8d5ae624a3c..2c3ec40833bbc 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -11,10 +11,6 @@ pub fn global_fn_name(base: Symbol) -> String { format!("__rust_{base}") } -pub fn default_fn_name(base: Symbol) -> String { - format!("__rdl_{base}") -} - pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str { match alloc_error_handler_kind { AllocatorKind::Global => "__rg_oom", diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 5e33b9d606fa5..8ab99edabfcd9 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -2,72 +2,34 @@ // Adapted from rustc use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, }; -use rustc_codegen_ssa::base::allocator_kind_for_codegen; +use rustc_codegen_ssa::base::needs_allocator_shim; use rustc_session::config::OomStrategy; use crate::prelude::*; /// Returns whether an allocator shim was created pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { - let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; - codegen_inner( - module, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); - true + if needs_allocator_shim(tcx) { + codegen_inner( + module, + tcx.alloc_error_handler_kind(()).unwrap(), + tcx.sess.opts.unstable_opts.oom, + ); + true + } else { + false + } } fn codegen_inner( module: &mut dyn Module, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, ) { let usize_ty = module.target_config().pointer_type(); - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut arg_tys = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - arg_tys.push(usize_ty); // size - arg_tys.push(usize_ty); // align - } - AllocatorTy::Ptr => arg_tys.push(usize_ty), - AllocatorTy::Usize => arg_tys.push(usize_ty), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), - } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(usize_ty), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: arg_tys.iter().cloned().map(AbiParam::new).collect(), - returns: output.into_iter().map(AbiParam::new).collect(), - }; - crate::common::create_wrapper_function( - module, - sig, - &global_fn_name(method.name), - &default_fn_name(method.name), - ); - } - } - let sig = Signature { call_conv: module.target_config().default_call_conv, params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 416f3231a13c4..54770476b4c5b 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -2,8 +2,7 @@ use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; #[cfg(feature = "master")] use gccjit::{FnAttribute, VarAttribute}; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; @@ -17,7 +16,6 @@ pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) { let context = &mods.context; @@ -28,37 +26,6 @@ pub(crate) unsafe fn codegen( tws => bug!("Unsupported target word size for int: {}", tws), }; let i8 = context.new_type::(); - let i8p = i8.make_pointer(); - - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut types = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - types.push(usize); - types.push(usize); - } - AllocatorTy::Ptr => types.push(i8p), - AllocatorTy::Usize => types.push(usize), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), - } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(i8p), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - let from_name = global_fn_name(method.name); - let to_name = default_fn_name(method.name); - - create_wrapper_function(tcx, context, &from_name, &to_name, &types, output); - } - } // FIXME(bjorn3): Add noreturn attribute create_wrapper_function( diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index f6ad0c79de545..85ed09e0505f9 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -290,7 +290,6 @@ impl ExtraBackendMethods for GccCodegenBackend { &self, tcx: TyCtxt<'_>, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> Self::Module { let mut mods = GccContext { @@ -301,7 +300,7 @@ impl ExtraBackendMethods for GccCodegenBackend { }; unsafe { - allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut mods, module_name, alloc_error_handler_kind); } mods } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 149ded28356b8..7353084c9b849 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,7 +1,6 @@ use libc::c_uint; use rustc_ast::expand::allocator::{ - ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, - alloc_error_handler_name, default_fn_name, global_fn_name, + AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, }; use rustc_middle::bug; use rustc_middle::ty::TyCtxt; @@ -15,7 +14,6 @@ pub(crate) unsafe fn codegen( tcx: TyCtxt<'_>, module_llvm: &mut ModuleLlvm, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) { let llcx = &*module_llvm.llcx; @@ -29,38 +27,6 @@ pub(crate) unsafe fn codegen( } }; let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) }; - let i8p = unsafe { llvm::LLVMPointerTypeInContext(llcx, 0) }; - - if kind == AllocatorKind::Default { - for method in ALLOCATOR_METHODS { - let mut args = Vec::with_capacity(method.inputs.len()); - for input in method.inputs.iter() { - match input.ty { - AllocatorTy::Layout => { - args.push(usize); // size - args.push(usize); // align - } - AllocatorTy::Ptr => args.push(i8p), - AllocatorTy::Usize => args.push(usize), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), - } - } - let output = match method.output { - AllocatorTy::ResultPtr => Some(i8p), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - - let from_name = global_fn_name(method.name); - let to_name = default_fn_name(method.name); - - create_wrapper_function(tcx, llcx, llmod, &from_name, &to_name, &args, output, false); - } - } // rust alloc error handler create_wrapper_function( diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 06afe8bb3ad54..1c7b52027e8f9 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -117,12 +117,11 @@ impl ExtraBackendMethods for LlvmCodegenBackend { &self, tcx: TyCtxt<'tcx>, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> ModuleLlvm { let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name); unsafe { - allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut module_llvm, module_name, alloc_error_handler_kind); } module_llvm } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 60ab291935256..f8040149f13b0 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -16,7 +16,7 @@ use rustc_session::config::{CrateType, OomStrategy}; use rustc_target::spec::{SanitizerSet, TlsModel}; use tracing::debug; -use crate::base::allocator_kind_for_codegen; +use crate::base::needs_allocator_shim; fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel { crates_export_threshold(tcx.crate_types()) @@ -206,7 +206,7 @@ fn exported_symbols_provider_local( } // Mark allocator shim symbols as exported only if they were generated. - if allocator_kind_for_codegen(tcx).is_some() { + if needs_allocator_shim(tcx) { for symbol_name in ALLOCATOR_METHODS .iter() .map(|method| format!("__rust_{}", method.name)) diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 544578b29f107..f57cb8983e62e 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -4,7 +4,7 @@ use std::time::{Duration, Instant}; use itertools::Itertools; use rustc_abi::FIRST_VARIANT; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name}; +use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, global_fn_name}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::{Lrc, par_map}; @@ -585,7 +585,7 @@ pub fn collect_debugger_visualizers_transitive( /// Decide allocator kind to codegen. If `Some(_)` this will be the same as /// `tcx.allocator_kind`, but it may be `None` in more cases (e.g. if using /// allocator definitions from a dylib dependency). -pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option { +pub fn needs_allocator_shim(tcx: TyCtxt<'_>) -> bool { // If the crate doesn't have an `allocator_kind` set then there's definitely // no shim to generate. Otherwise we also check our dependency graph for all // our output crate types. If anything there looks like its a `Dynamic` @@ -596,7 +596,7 @@ pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option { use rustc_middle::middle::dependency_format::Linkage; list.iter().any(|&linkage| linkage == Linkage::Dynamic) }); - if any_dynamic_crate { None } else { tcx.allocator_kind(()) } + if any_dynamic_crate { false } else { tcx.allocator_kind(()).is_some() } } pub fn codegen_crate( @@ -665,14 +665,13 @@ pub fn codegen_crate( start_async_codegen(backend.clone(), tcx, target_cpu, metadata, metadata_module); // Codegen an allocator shim, if necessary. - if let Some(kind) = allocator_kind_for_codegen(tcx) { + if needs_allocator_shim(tcx) { let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); let module_llvm = tcx.sess.time("write_allocator_module", || { backend.codegen_allocator( tcx, &llmod_id, - kind, // If allocator_kind is Some then alloc_error_handler_kind must // also be Some. tcx.alloc_error_handler_kind(()).unwrap(), diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index ebcf118b90380..1d12172153821 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -104,7 +104,6 @@ pub trait ExtraBackendMethods: &self, tcx: TyCtxt<'tcx>, module_name: &str, - kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> Self::Module; diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 6512176cc4a90..2e4a49df4d9ef 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -1164,6 +1164,8 @@ fn global_allocator_spans(krate: &ast::Crate) -> Vec { fn visit_item(&mut self, item: &'ast ast::Item) { if item.ident.name == self.name && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) + // Ignore the default allocator in libstd with weak linkage + && attr::find_by_name(&item.attrs, sym::linkage).is_none() { self.spans.push(item.span); } diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index 7b17966343084..e4933c08208bf 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -887,6 +887,7 @@ fn mono_item_visibility<'tcx>( // Removal of these functions can't be done by LLVM but rather must be // done by the linker as it's a non-local decision. // + // FIXME update comment // * Second is "std internal symbols". Currently this is primarily used // for allocator symbols. Allocators are a little weird in their // implementation, but the idea is that the compiler, at the last diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index e9b7f9856677c..8d46ddd9e0edd 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,7 +14,7 @@ extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute // (the code expanding that attribute macro generates those functions), or to call - // the default implementations in std (`__rdl_alloc` etc. in `library/std/src/alloc.rs`) + // the default implementations in std (weak symbols in `library/std/src/alloc.rs`) // otherwise. // The rustc fork of LLVM 14 and earlier also special-cases these function names to be able to optimize them // like `malloc`, `realloc`, and `free`, respectively. diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 5d51d6a0c78a8..24b982c3e964b 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -382,9 +382,8 @@ pub fn rust_oom(layout: Layout) -> ! { #[unstable(feature = "alloc_internals", issue = "none")] pub mod __default_lib_allocator { use super::{GlobalAlloc, Layout, System}; - // These magic symbol names are used as a fallback for implementing the - // `__rust_alloc` etc symbols (see `src/liballoc/alloc.rs`) when there is - // no `#[global_allocator]` attribute. + // These are used as a fallback for implementing the `__rust_alloc`, etc symbols + // (see `src/liballoc/alloc.rs`) when there is no `#[global_allocator]` attribute. // for symbol names src/librustc_ast/expand/allocator.rs // for signatures src/librustc_allocator/lib.rs @@ -393,7 +392,8 @@ pub mod __default_lib_allocator { // ABI #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_alloc(size: usize, align: usize) -> *mut u8 { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_alloc(size: usize, align: usize) -> *mut u8 { // SAFETY: see the guarantees expected by `Layout::from_size_align` and // `GlobalAlloc::alloc`. unsafe { @@ -403,14 +403,16 @@ pub mod __default_lib_allocator { } #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize) { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize) { // SAFETY: see the guarantees expected by `Layout::from_size_align` and // `GlobalAlloc::dealloc`. unsafe { System.dealloc(ptr, Layout::from_size_align_unchecked(size, align)) } } #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_realloc( + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_realloc( ptr: *mut u8, old_size: usize, align: usize, @@ -425,7 +427,8 @@ pub mod __default_lib_allocator { } #[rustc_std_internal_symbol] - pub unsafe extern "C" fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 { // SAFETY: see the guarantees expected by `Layout::from_size_align` and // `GlobalAlloc::alloc_zeroed`. unsafe { diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 25c0b52d0618b..2e9f6287c212d 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -1,7 +1,6 @@ use std::iter; use rustc_abi::{Align, Size}; -use rustc_ast::expand::allocator::AllocatorKind; use crate::*; @@ -53,31 +52,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } /// Emulates calling the internal __rust_* allocator functions - fn emulate_allocator( - &mut self, - default: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx>, - ) -> InterpResult<'tcx, EmulateItemResult> { - let this = self.eval_context_mut(); - - let Some(allocator_kind) = this.tcx.allocator_kind(()) else { - // in real code, this symbol does not exist without an allocator - return interp_ok(EmulateItemResult::NotSupported); - }; - - match allocator_kind { - AllocatorKind::Global => { - // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion - // of this attribute. As such we have to call an exported Rust function, - // and not execute any Miri shim. Somewhat unintuitively doing so is done - // by returning `NotSupported`, which triggers the `lookup_exported_symbol` - // fallback case in `emulate_foreign_item`. - interp_ok(EmulateItemResult::NotSupported) - } - AllocatorKind::Default => { - default(this)?; - interp_ok(EmulateItemResult::NeedsReturn) - } - } + fn emulate_allocator(&mut self) -> InterpResult<'tcx, EmulateItemResult> { + // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion + // of this attribute. As such we have to call an exported Rust function, + // and not execute any Miri shim. Somewhat unintuitively doing so is done + // by returning `NotSupported`, which triggers the `lookup_exported_symbol` + // fallback case in `emulate_foreign_item`. + interp_ok(EmulateItemResult::NotSupported) } fn malloc(&mut self, size: u64, zero_init: bool) -> InterpResult<'tcx, Pointer> { diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 6c8ccc8398590..9019201cda549 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -1,6 +1,5 @@ use std::collections::hash_map::Entry; use std::io::Write; -use std::iter; use std::path::Path; use rustc_abi::{Align, AlignFromBytesError, Size}; @@ -9,6 +8,7 @@ use rustc_ast::expand::allocator::alloc_error_handler_name; use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; use rustc_span::Symbol; @@ -134,7 +134,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Entry::Occupied(e) => e.into_mut(), Entry::Vacant(e) => { // Find it if it was not cached. - let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum)> = None; + let mut instance_and_crate: Option<(ty::Instance<'_>, CrateNum, bool)> = None; helpers::iter_exported_symbols(tcx, |cnum, def_id| { let attrs = tcx.codegen_fn_attrs(def_id); let symbol_name = if let Some(export_name) = attrs.export_name { @@ -145,39 +145,71 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { // Skip over items without an explicitly defined symbol name. return interp_ok(()); }; + let is_weak = + attrs.linkage.map_or(false, |linkage| linkage == Linkage::WeakAny); if symbol_name == link_name { - if let Some((original_instance, original_cnum)) = instance_and_crate { - // Make sure we are consistent wrt what is 'first' and 'second'. - let original_span = tcx.def_span(original_instance.def_id()).data(); - let span = tcx.def_span(def_id).data(); - if original_span < span { - throw_machine_stop!(TerminationInfo::MultipleSymbolDefinitions { - link_name, - first: original_span, - first_crate: tcx.crate_name(original_cnum), - second: span, - second_crate: tcx.crate_name(cnum), - }); - } else { - throw_machine_stop!(TerminationInfo::MultipleSymbolDefinitions { - link_name, - first: span, - first_crate: tcx.crate_name(cnum), - second: original_span, - second_crate: tcx.crate_name(original_cnum), - }); + if let Some((original_instance, original_cnum, original_is_weak)) = + instance_and_crate + { + match (is_weak, original_is_weak) { + (false, true) => { + // Original definition is a weak definition. Override it. + + instance_and_crate = + Some((ty::Instance::mono(tcx, def_id), cnum, is_weak)); + } + (true, false) => { + // Current definition is a weak definition. Keep the original one. + } + (true, true) | (false, false) => { + // Either both definitions are non-weak or both are weak. In + // either case return an error. For weak definitions we error + // because it is undefined which definition would have been + // picked by the linker. + + // Make sure we are consistent wrt what is 'first' and 'second'. + let original_span = + tcx.def_span(original_instance.def_id()).data(); + let span = tcx.def_span(def_id).data(); + if original_span < span { + throw_machine_stop!( + TerminationInfo::MultipleSymbolDefinitions { + link_name, + first: original_span, + first_crate: tcx.crate_name(original_cnum), + second: span, + second_crate: tcx.crate_name(cnum), + } + ); + } else { + throw_machine_stop!( + TerminationInfo::MultipleSymbolDefinitions { + link_name, + first: span, + first_crate: tcx.crate_name(cnum), + second: original_span, + second_crate: tcx.crate_name(original_cnum), + } + ); + } + } } + } else { + instance_and_crate = + Some((ty::Instance::mono(tcx, def_id), cnum, is_weak)); } - if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) { - throw_ub_format!( - "attempt to call an exported symbol that is not defined as a function" - ); - } - instance_and_crate = Some((ty::Instance::mono(tcx, def_id), cnum)); } interp_ok(()) })?; + if let Some((instance, _, _)) = instance_and_crate { + if !matches!(tcx.def_kind(instance.def_id()), DefKind::Fn | DefKind::AssocFn) { + throw_ub_format!( + "attempt to call an exported symbol that is not defined as a function" + ); + } + } + e.insert(instance_and_crate.map(|ic| ic.0)) } }; @@ -515,7 +547,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { }; match link_name.as_str() { - "__rust_alloc" => return this.emulate_allocator(default), + "__rust_alloc" => return this.emulate_allocator(), "miri_alloc" => { default(this)?; return interp_ok(EmulateItemResult::NeedsReturn); @@ -524,29 +556,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "__rust_alloc_zeroed" => { - return this.emulate_allocator(|this| { - // See the comment for `__rust_alloc` why `check_shim` is only called in the - // default case. - let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; - let size = this.read_target_usize(size)?; - let align = this.read_target_usize(align)?; - - this.check_rustc_alloc_request(size, align)?; - - let ptr = this.allocate_ptr( - Size::from_bytes(size), - Align::from_bytes(align).unwrap(), - MiriMemoryKind::Rust.into(), - )?; - - // We just allocated this, the access is definitely in-bounds. - this.write_bytes_ptr( - ptr.into(), - iter::repeat(0u8).take(usize::try_from(size).unwrap()), - ) - .unwrap(); - this.write_pointer(ptr, dest) - }); + return this.emulate_allocator(); } "__rust_dealloc" | "miri_dealloc" => { let default = |ecx: &mut MiriInterpCx<'tcx>| { @@ -574,7 +584,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { match link_name.as_str() { "__rust_dealloc" => { - return this.emulate_allocator(default); + return this.emulate_allocator(); } "miri_dealloc" => { default(this)?; @@ -584,29 +594,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } } "__rust_realloc" => { - return this.emulate_allocator(|this| { - // See the comment for `__rust_alloc` why `check_shim` is only called in the - // default case. - let [ptr, old_size, align, new_size] = - this.check_shim(abi, Conv::Rust, link_name, args)?; - let ptr = this.read_pointer(ptr)?; - let old_size = this.read_target_usize(old_size)?; - let align = this.read_target_usize(align)?; - let new_size = this.read_target_usize(new_size)?; - // No need to check old_size; we anyway check that they match the allocation. - - this.check_rustc_alloc_request(new_size, align)?; - - let align = Align::from_bytes(align).unwrap(); - let new_ptr = this.reallocate_ptr( - ptr, - Some((Size::from_bytes(old_size), align)), - Size::from_bytes(new_size), - align, - MiriMemoryKind::Rust.into(), - )?; - this.write_pointer(new_ptr, dest) - }); + return this.emulate_allocator(); } // C memory handling functions From 4387a583ec1d9767fbda377390901b6f3a4ac598 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 09:15:04 +0000 Subject: [PATCH 2/8] Update comments and simplify miri allocator handling a bit --- .../src/back/symbol_export.rs | 8 +- .../rustc_monomorphize/src/partitioning.rs | 15 +-- library/std/src/alloc.rs | 3 +- src/tools/miri/src/shims/alloc.rs | 10 -- src/tools/miri/src/shims/foreign_items.rs | 91 +++++-------------- 5 files changed, 29 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index f8040149f13b0..0d5761ed9afae 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -1,6 +1,6 @@ use std::collections::hash_map::Entry::*; -use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE}; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_data_structures::unord::UnordMap; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId}; @@ -207,10 +207,8 @@ fn exported_symbols_provider_local( // Mark allocator shim symbols as exported only if they were generated. if needs_allocator_shim(tcx) { - for symbol_name in ALLOCATOR_METHODS - .iter() - .map(|method| format!("__rust_{}", method.name)) - .chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()]) + for symbol_name in + ["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()] { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs index e4933c08208bf..cb3f83984578f 100644 --- a/compiler/rustc_monomorphize/src/partitioning.rs +++ b/compiler/rustc_monomorphize/src/partitioning.rs @@ -889,18 +889,9 @@ fn mono_item_visibility<'tcx>( // // FIXME update comment // * Second is "std internal symbols". Currently this is primarily used - // for allocator symbols. Allocators are a little weird in their - // implementation, but the idea is that the compiler, at the last - // minute, defines an allocator with an injected object file. The - // `alloc` crate references these symbols (`__rust_alloc`) and the - // definition doesn't get hooked up until a linked crate artifact is - // generated. - // - // The symbols synthesized by the compiler (`__rust_alloc`) are thin - // veneers around the actual implementation, some other symbol which - // implements the same ABI. These symbols (things like `__rg_alloc`, - // `__rdl_alloc`, `__rde_alloc`, etc), are all tagged with "std - // internal symbols". + // for allocator symbols and the unwinder runtime to allow cyclic + // dependencies between the defining and using crate and to allow + // replacing them. // // The std-internal symbols here **should not show up in a dll as an // exported interface**, so they return `false` from diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 24b982c3e964b..300f530ca764b 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -385,8 +385,7 @@ pub mod __default_lib_allocator { // These are used as a fallback for implementing the `__rust_alloc`, etc symbols // (see `src/liballoc/alloc.rs`) when there is no `#[global_allocator]` attribute. - // for symbol names src/librustc_ast/expand/allocator.rs - // for signatures src/librustc_allocator/lib.rs + // for symbol names and signatures see compiler/rustc_ast/src/expand/allocator.rs // linkage directives are provided as part of the current compiler allocator // ABI diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 2e9f6287c212d..4dc9ba354a05a 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -51,16 +51,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Align::from_bytes(prev_power_of_two(size)).unwrap() } - /// Emulates calling the internal __rust_* allocator functions - fn emulate_allocator(&mut self) -> InterpResult<'tcx, EmulateItemResult> { - // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion - // of this attribute. As such we have to call an exported Rust function, - // and not execute any Miri shim. Somewhat unintuitively doing so is done - // by returning `NotSupported`, which triggers the `lookup_exported_symbol` - // fallback case in `emulate_foreign_item`. - interp_ok(EmulateItemResult::NotSupported) - } - fn malloc(&mut self, size: u64, zero_init: bool) -> InterpResult<'tcx, Pointer> { let this = self.eval_context_mut(); let align = this.malloc_align(size); diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 9019201cda549..b1122e882010b 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -521,80 +521,33 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Rust allocation - "__rust_alloc" | "miri_alloc" => { - let default = |ecx: &mut MiriInterpCx<'tcx>| { - // Only call `check_shim` when `#[global_allocator]` isn't used. When that - // macro is used, we act like no shim exists, so that the exported function can run. - let [size, align] = ecx.check_shim(abi, Conv::Rust, link_name, args)?; - let size = ecx.read_target_usize(size)?; - let align = ecx.read_target_usize(align)?; - - ecx.check_rustc_alloc_request(size, align)?; - - let memory_kind = match link_name.as_str() { - "__rust_alloc" => MiriMemoryKind::Rust, - "miri_alloc" => MiriMemoryKind::Miri, - _ => unreachable!(), - }; + "miri_alloc" => { + let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let size = this.read_target_usize(size)?; + let align = this.read_target_usize(align)?; - let ptr = ecx.allocate_ptr( - Size::from_bytes(size), - Align::from_bytes(align).unwrap(), - memory_kind.into(), - )?; + this.check_rustc_alloc_request(size, align)?; - ecx.write_pointer(ptr, dest) - }; + let ptr = this.allocate_ptr( + Size::from_bytes(size), + Align::from_bytes(align).unwrap(), + MiriMemoryKind::Miri.into(), + )?; - match link_name.as_str() { - "__rust_alloc" => return this.emulate_allocator(), - "miri_alloc" => { - default(this)?; - return interp_ok(EmulateItemResult::NeedsReturn); - } - _ => unreachable!(), - } + this.write_pointer(ptr, dest)?; } - "__rust_alloc_zeroed" => { - return this.emulate_allocator(); - } - "__rust_dealloc" | "miri_dealloc" => { - let default = |ecx: &mut MiriInterpCx<'tcx>| { - // See the comment for `__rust_alloc` why `check_shim` is only called in the - // default case. - let [ptr, old_size, align] = - ecx.check_shim(abi, Conv::Rust, link_name, args)?; - let ptr = ecx.read_pointer(ptr)?; - let old_size = ecx.read_target_usize(old_size)?; - let align = ecx.read_target_usize(align)?; - - let memory_kind = match link_name.as_str() { - "__rust_dealloc" => MiriMemoryKind::Rust, - "miri_dealloc" => MiriMemoryKind::Miri, - _ => unreachable!(), - }; - - // No need to check old_size/align; we anyway check that they match the allocation. - ecx.deallocate_ptr( - ptr, - Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())), - memory_kind.into(), - ) - }; + "miri_dealloc" => { + let [ptr, old_size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let ptr = this.read_pointer(ptr)?; + let old_size = this.read_target_usize(old_size)?; + let align = this.read_target_usize(align)?; - match link_name.as_str() { - "__rust_dealloc" => { - return this.emulate_allocator(); - } - "miri_dealloc" => { - default(this)?; - return interp_ok(EmulateItemResult::NeedsReturn); - } - _ => unreachable!(), - } - } - "__rust_realloc" => { - return this.emulate_allocator(); + // No need to check old_size/align; we anyway check that they match the allocation. + this.deallocate_ptr( + ptr, + Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())), + MiriMemoryKind::Miri.into(), + )?; } // C memory handling functions From cbb0df4b40e93dc7046f43a9fa63ba5d51a97e63 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:14:18 +0000 Subject: [PATCH 3/8] Use weak linkage for the alloc error handler too --- compiler/rustc_ast/src/expand/allocator.rs | 7 -- .../src/alloc_error_handler.rs | 5 +- .../rustc_codegen_cranelift/src/allocator.rs | 30 +---- compiler/rustc_codegen_gcc/src/allocator.rs | 100 +-------------- compiler/rustc_codegen_gcc/src/lib.rs | 10 +- compiler/rustc_codegen_llvm/src/allocator.rs | 114 +----------------- compiler/rustc_codegen_llvm/src/lib.rs | 10 +- .../src/back/symbol_export.rs | 17 +-- compiler/rustc_codegen_ssa/src/base.rs | 11 +- .../rustc_codegen_ssa/src/traits/backend.rs | 8 +- compiler/rustc_metadata/src/creader.rs | 12 +- .../src/rmeta/decoder/cstore_impl.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 4 - library/alloc/src/alloc.rs | 9 +- library/alloc/src/lib.rs | 1 + library/std/src/alloc.rs | 7 +- src/tools/miri/src/shims/foreign_items.rs | 20 --- 17 files changed, 41 insertions(+), 325 deletions(-) diff --git a/compiler/rustc_ast/src/expand/allocator.rs b/compiler/rustc_ast/src/expand/allocator.rs index 2c3ec40833bbc..97cef7d08ac4e 100644 --- a/compiler/rustc_ast/src/expand/allocator.rs +++ b/compiler/rustc_ast/src/expand/allocator.rs @@ -11,13 +11,6 @@ pub fn global_fn_name(base: Symbol) -> String { format!("__rust_{base}") } -pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str { - match alloc_error_handler_kind { - AllocatorKind::Global => "__rg_oom", - AllocatorKind::Default => "__rdl_oom", - } -} - pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable"; pub enum AllocatorTy { diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index d2b4e1ca824fd..acde6323b061d 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -56,7 +56,7 @@ pub(crate) fn expand( } // #[rustc_std_internal_symbol] -// unsafe fn __rg_oom(size: usize, align: usize) -> ! { +// unsafe fn __rust_alloc_error_handler(size: usize, align: usize) -> ! { // handler(core::alloc::Layout::from_size_align_unchecked(size, align)) // } fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { @@ -90,6 +90,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; - let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind); + let item = + cx.item(span, Ident::from_str_and_span("__rust_alloc_error_handler", span), attrs, kind); cx.stmt_item(sig_span, item) } diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 8ab99edabfcd9..5805f738d0a1a 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -1,9 +1,7 @@ //! Allocator shim // Adapted from rustc -use rustc_ast::expand::allocator::{ - AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, -}; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_codegen_ssa::base::needs_allocator_shim; use rustc_session::config::OomStrategy; @@ -12,36 +10,14 @@ use crate::prelude::*; /// Returns whether an allocator shim was created pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool { if needs_allocator_shim(tcx) { - codegen_inner( - module, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); + codegen_inner(module, tcx.sess.opts.unstable_opts.oom); true } else { false } } -fn codegen_inner( - module: &mut dyn Module, - alloc_error_handler_kind: AllocatorKind, - oom_strategy: OomStrategy, -) { - let usize_ty = module.target_config().pointer_type(); - - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], - }; - crate::common::create_wrapper_function( - module, - sig, - "__rust_alloc_error_handler", - &alloc_error_handler_name(alloc_error_handler_kind), - ); - +fn codegen_inner(module: &mut dyn Module, oom_strategy: OomStrategy) { let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); let mut data = DataDescription::new(); data.set_align(1); diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 54770476b4c5b..5cf8d27f884e2 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -1,10 +1,7 @@ -use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; +use gccjit::GlobalKind; #[cfg(feature = "master")] -use gccjit::{FnAttribute, VarAttribute}; -use rustc_ast::expand::allocator::{ - AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, -}; -use rustc_middle::bug; +use gccjit::VarAttribute; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; @@ -12,31 +9,10 @@ use crate::GccContext; #[cfg(feature = "master")] use crate::base::symbol_visibility_to_gcc; -pub(crate) unsafe fn codegen( - tcx: TyCtxt<'_>, - mods: &mut GccContext, - _module_name: &str, - alloc_error_handler_kind: AllocatorKind, -) { +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str) { let context = &mods.context; - let usize = match tcx.sess.target.pointer_width { - 16 => context.new_type::(), - 32 => context.new_type::(), - 64 => context.new_type::(), - tws => bug!("Unsupported target word size for int: {}", tws), - }; let i8 = context.new_type::(); - // FIXME(bjorn3): Add noreturn attribute - create_wrapper_function( - tcx, - context, - "__rust_alloc_error_handler", - alloc_error_handler_name(alloc_error_handler_kind), - &[usize, usize], - None, - ); - let name = OomStrategy::SYMBOL.to_string(); let global = context.new_global(None, GlobalKind::Exported, i8, name); #[cfg(feature = "master")] @@ -56,71 +32,3 @@ pub(crate) unsafe fn codegen( let value = context.new_rvalue_from_int(i8, 0); global.global_set_initializer_rvalue(value); } - -fn create_wrapper_function( - tcx: TyCtxt<'_>, - context: &Context<'_>, - from_name: &str, - to_name: &str, - types: &[Type<'_>], - output: Option>, -) { - let void = context.new_type::<()>(); - - let args: Vec<_> = types - .iter() - .enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, format!("param{}", index))) - .collect(); - let func = context.new_function( - None, - FunctionType::Exported, - output.unwrap_or(void), - &args, - from_name, - false, - ); - - #[cfg(feature = "master")] - func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc( - tcx.sess.default_visibility(), - ))); - - if tcx.sess.must_emit_unwind_tables() { - // 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); - } else { - block.end_with_void_return(None); - } - - // TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances - // as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643 -} diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 85ed09e0505f9..7d94e866b899b 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -93,7 +93,6 @@ use back::lto::{ThinBuffer, ThinData}; use gccjit::{CType, Context, OptimizationLevel}; #[cfg(feature = "master")] use gccjit::{TargetInfo, Version}; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ @@ -286,12 +285,7 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { } impl ExtraBackendMethods for GccCodegenBackend { - fn codegen_allocator( - &self, - tcx: TyCtxt<'_>, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, - ) -> Self::Module { + fn codegen_allocator(&self, tcx: TyCtxt<'_>, module_name: &str) -> Self::Module { let mut mods = GccContext { context: Arc::new(SyncContext::new(new_context(tcx))), relocation_model: tcx.sess.relocation_model(), @@ -300,7 +294,7 @@ impl ExtraBackendMethods for GccCodegenBackend { }; unsafe { - allocator::codegen(tcx, &mut mods, module_name, alloc_error_handler_kind); + allocator::codegen(tcx, &mut mods, module_name); } mods } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 7353084c9b849..5d7f7444ec208 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -1,45 +1,16 @@ -use libc::c_uint; -use rustc_ast::expand::allocator::{ - AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, -}; -use rustc_middle::bug; +use rustc_ast::expand::allocator::NO_ALLOC_SHIM_IS_UNSTABLE; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; use crate::common::AsCCharPtr; -use crate::llvm::{self, Context, False, Module, True, Type}; -use crate::{ModuleLlvm, attributes, debuginfo}; +use crate::llvm::{self, False}; +use crate::{ModuleLlvm, debuginfo}; -pub(crate) unsafe fn codegen( - tcx: TyCtxt<'_>, - module_llvm: &mut ModuleLlvm, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, -) { +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, module_llvm: &mut ModuleLlvm, module_name: &str) { let llcx = &*module_llvm.llcx; let llmod = module_llvm.llmod(); - let usize = unsafe { - match tcx.sess.target.pointer_width { - 16 => llvm::LLVMInt16TypeInContext(llcx), - 32 => llvm::LLVMInt32TypeInContext(llcx), - 64 => llvm::LLVMInt64TypeInContext(llcx), - tws => bug!("Unsupported target word size for int: {}", tws), - } - }; let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) }; - // rust alloc error handler - create_wrapper_function( - tcx, - llcx, - llmod, - "__rust_alloc_error_handler", - alloc_error_handler_name(alloc_error_handler_kind), - &[usize, usize], // size, align - None, - true, - ); - unsafe { // __rust_alloc_error_handler_should_panic let name = OomStrategy::SYMBOL; @@ -62,80 +33,3 @@ pub(crate) unsafe fn codegen( dbg_cx.finalize(tcx.sess); } } - -fn create_wrapper_function( - tcx: TyCtxt<'_>, - llcx: &Context, - llmod: &Module, - from_name: &str, - to_name: &str, - args: &[&Type], - output: Option<&Type>, - no_return: bool, -) { - unsafe { - let ty = llvm::LLVMFunctionType( - output.unwrap_or_else(|| llvm::LLVMVoidTypeInContext(llcx)), - args.as_ptr(), - args.len() as c_uint, - False, - ); - let llfn = llvm::LLVMRustGetOrInsertFunction( - llmod, - from_name.as_c_char_ptr(), - from_name.len(), - ty, - ); - let no_return = if no_return { - // -> ! DIFlagNoReturn - let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]); - Some(no_return) - } else { - None - }; - - llvm::set_visibility(llfn, llvm::Visibility::from_generic(tcx.sess.default_visibility())); - - if tcx.sess.must_emit_unwind_tables() { - let uwtable = - attributes::uwtable_attr(llcx, tcx.sess.opts.unstable_opts.use_sync_unwind); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); - } - - let callee = - llvm::LLVMRustGetOrInsertFunction(llmod, to_name.as_c_char_ptr(), to_name.len(), 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 = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, c"entry".as_ptr()); - - let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); - llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); - let args = args - .iter() - .enumerate() - .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) - .collect::>(); - let ret = llvm::LLVMBuildCallWithOperandBundles( - llbuilder, - ty, - callee, - args.as_ptr(), - args.len() as c_uint, - [].as_ptr(), - 0 as c_uint, - c"".as_ptr(), - ); - llvm::LLVMSetTailCall(ret, True); - if output.is_some() { - llvm::LLVMBuildRet(llbuilder, ret); - } else { - llvm::LLVMBuildRetVoid(llbuilder); - } - llvm::LLVMDisposeBuilder(llbuilder); - } -} diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 1c7b52027e8f9..c2b02d3f6565f 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -30,7 +30,6 @@ use back::owned_target_machine::OwnedTargetMachine; use back::write::{create_informational_target_machine, create_target_machine}; use errors::{AutoDiffWithoutLTO, ParseTargetMachineConfig}; pub use llvm_util::target_features_cfg; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_ast::expand::autodiff_attrs::AutoDiffItem; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::write::{ @@ -113,15 +112,10 @@ impl Drop for TimeTraceProfiler { } impl ExtraBackendMethods for LlvmCodegenBackend { - fn codegen_allocator<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, - ) -> ModuleLlvm { + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str) -> ModuleLlvm { let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name); unsafe { - allocator::codegen(tcx, &mut module_llvm, module_name, alloc_error_handler_kind); + allocator::codegen(tcx, &mut module_llvm, module_name); } module_llvm } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 0d5761ed9afae..17bdbef5c9883 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -207,17 +207,12 @@ fn exported_symbols_provider_local( // Mark allocator shim symbols as exported only if they were generated. if needs_allocator_shim(tcx) { - for symbol_name in - ["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()] - { - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); - - symbols.push((exported_symbol, SymbolExportInfo { - level: SymbolExportLevel::Rust, - kind: SymbolExportKind::Text, - used: false, - })); - } + let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &OomStrategy::SYMBOL)); + symbols.push((exported_symbol, SymbolExportInfo { + level: SymbolExportLevel::Rust, + kind: SymbolExportKind::Text, + used: false, + })); let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, NO_ALLOC_SHIM_IS_UNSTABLE)); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f57cb8983e62e..0b482d5cffb21 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -668,15 +668,8 @@ pub fn codegen_crate( if needs_allocator_shim(tcx) { let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); - let module_llvm = tcx.sess.time("write_allocator_module", || { - backend.codegen_allocator( - tcx, - &llmod_id, - // If allocator_kind is Some then alloc_error_handler_kind must - // also be Some. - tcx.alloc_error_handler_kind(()).unwrap(), - ) - }); + let module_llvm = + tcx.sess.time("write_allocator_module", || backend.codegen_allocator(tcx, &llmod_id)); ongoing_codegen.wait_for_signal_to_codegen_item(); ongoing_codegen.check_for_errors(tcx.sess); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 1d12172153821..ff5a001fb82e5 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -1,7 +1,6 @@ use std::any::Any; use std::hash::Hash; -use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_metadata::EncodedMetadata; @@ -100,12 +99,7 @@ pub trait CodegenBackend { pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync { - fn codegen_allocator<'tcx>( - &self, - tcx: TyCtxt<'tcx>, - module_name: &str, - alloc_error_handler_kind: AllocatorKind, - ) -> Self::Module; + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str) -> Self::Module; /// This generates the codegen unit and returns it along with /// a `u64` giving an estimate of the unit's processing cost. diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 2e4a49df4d9ef..3122289ec5c5e 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -8,7 +8,7 @@ use std::time::Duration; use std::{cmp, env, iter}; use proc_macro::bridge::client::ProcMacro; -use rustc_ast::expand::allocator::{AllocatorKind, alloc_error_handler_name, global_fn_name}; +use rustc_ast::expand::allocator::{AllocatorKind, global_fn_name}; use rustc_ast::{self as ast, *}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::owned_slice::OwnedSlice; @@ -23,7 +23,7 @@ use rustc_hir::definitions::Definitions; use rustc_index::IndexVec; use rustc_middle::bug; use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; -use rustc_session::config::{self, CrateType, ExternLocation}; +use rustc_session::config::{self, CrateType, ExternLocation, OomStrategy}; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; use rustc_session::lint::{self, BuiltinLintDiag}; use rustc_session::output::validate_crate_name; @@ -264,10 +264,6 @@ impl CStore { self.allocator_kind } - pub(crate) fn alloc_error_handler_kind(&self) -> Option { - self.alloc_error_handler_kind - } - pub(crate) fn has_global_allocator(&self) -> bool { self.has_global_allocator } @@ -1188,6 +1184,8 @@ fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec { fn visit_item(&mut self, item: &'ast ast::Item) { if item.ident.name == self.name && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) + // Ignore the default alloc error handler in libstd with weak linkage + && attr::find_by_name(&item.attrs, sym::linkage).is_none() { self.spans.push(item.span); } @@ -1195,7 +1193,7 @@ fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec { } } - let name = Symbol::intern(alloc_error_handler_name(AllocatorKind::Global)); + let name = Symbol::intern(OomStrategy::SYMBOL); let mut f = Finder { name, spans: Vec::new() }; visit::walk_crate(&mut f, krate); f.spans diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 527f2f10205a6..5211e650acbe8 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -435,7 +435,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { provide_cstore_hooks(providers); providers.queries = rustc_middle::query::Providers { allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), - alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), is_private_dep: |_tcx, LocalCrate| false, native_library: |tcx, id| { tcx.native_libraries(id.krate) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index bfbcb0532c10e..3ba470268670d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2109,10 +2109,6 @@ rustc_queries! { eval_always desc { "getting the allocator kind for the current crate" } } - query alloc_error_handler_kind(_: ()) -> Option { - eval_always - desc { "alloc error handler kind for the current crate" } - } query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap> { desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 8d46ddd9e0edd..958659bb5399e 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -357,8 +357,8 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg(not(no_global_oom_handling))] extern "Rust" { // This is the magic symbol to call the global alloc error handler. rustc generates - // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the - // default implementations below (`__rdl_oom`) otherwise. + // it if there is a `#[alloc_error_handler]`, or to the weak implementations below + // is called otherwise. fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } @@ -422,10 +422,9 @@ pub use std::alloc::handle_alloc_error; #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] pub mod __alloc_error_handler { - // called via generated `__rust_alloc_error_handler` if there is no - // `#[alloc_error_handler]`. #[rustc_std_internal_symbol] - pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { + #[linkage = "weak"] + pub unsafe extern "Rust" fn __rust_alloc_error_handler(size: usize, _align: usize) -> ! { extern "Rust" { // This symbol is emitted by rustc next to __rust_alloc_error_handler. // Its value depends on the -Zoom={panic,abort} compiler option. diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index b4f08debc932a..16a42d25eaa7a 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -123,6 +123,7 @@ #![feature(iter_next_chunk)] #![feature(layout_for_ptr)] #![feature(legacy_receiver_trait)] +#![feature(linkage)] #![feature(local_waker)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array_transpose)] diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 300f530ca764b..849ef537aa4ef 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -357,9 +357,10 @@ fn default_alloc_error_hook(layout: Layout) { // This is the default path taken on OOM, and the only path taken on stable with std. // Crucially, it does *not* call any user-defined code, and therefore users do not have to // worry about allocation failure causing reentrancy issues. That makes it different from - // the default `__rdl_oom` defined in alloc (i.e., the default alloc error handler that is - // called when there is no `#[alloc_error_handler]`), which triggers a regular panic and - // thus can invoke a user-defined panic hook, executing arbitrary user-defined code. + // the default `__rust_alloc_error_handler` defined in alloc (i.e., the default alloc error + // handler that is called when there is no `#[alloc_error_handler]`), which triggers a + // regular panic and thus can invoke a user-defined panic hook, executing arbitrary + // user-defined code. rtprintpanic!("memory allocation of {} bytes failed\n", layout.size()); } } diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index b1122e882010b..0970d768f8b58 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -4,7 +4,6 @@ use std::path::Path; use rustc_abi::{Align, AlignFromBytesError, Size}; use rustc_apfloat::Float; -use rustc_ast::expand::allocator::alloc_error_handler_name; use rustc_hir::def::DefKind; use rustc_hir::def_id::CrateNum; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; @@ -49,25 +48,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { ) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> { let this = self.eval_context_mut(); - // Some shims forward to other MIR bodies. - match link_name.as_str() { - "__rust_alloc_error_handler" => { - // Forward to the right symbol that implements this function. - let Some(handler_kind) = this.tcx.alloc_error_handler_kind(()) else { - // in real code, this symbol does not exist without an allocator - throw_unsup_format!( - "`__rust_alloc_error_handler` cannot be called when no alloc error handler is set" - ); - }; - let name = alloc_error_handler_name(handler_kind); - let handler = this - .lookup_exported_symbol(Symbol::intern(name))? - .expect("missing alloc error handler symbol"); - return interp_ok(Some(handler)); - } - _ => {} - } - // The rest either implements the logic, or falls back to `lookup_exported_symbol`. match this.emulate_foreign_item_inner(link_name, abi, args, dest)? { EmulateItemResult::NeedsReturn => { From 6416a64e0c338151e609b30c9037de112284e691 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 10:42:40 +0000 Subject: [PATCH 4/8] Bless miri tests --- library/alloc/src/alloc.rs | 10 +- .../fail/alloc/alloc_error_handler.stderr | 2 +- .../alloc/alloc_error_handler_custom.stderr | 2 +- .../alloc/alloc_error_handler_no_std.stderr | 2 +- .../alloc/deallocate-bad-alignment.stderr | 15 -- .../fail/alloc/deallocate-bad-size.stderr | 15 -- .../tests/fail/alloc/deallocate-twice.stderr | 14 +- .../fail/alloc/global_system_mixup.stderr | 21 --- .../fail/alloc/reallocate-bad-size.stderr | 20 ++- .../fail/alloc/reallocate-dangling.stderr | 14 +- .../miri/tests/fail/alloc/stack_free.stderr | 10 +- .../miri/tests/fail/alloc/too_large.stderr | 30 +++- .../alloc/unsupported_big_alignment.stderr | 144 ++++++++++++++++-- ...unsupported_non_power_two_alignment.stderr | 30 +++- .../newtype_pair_retagging.tree.stderr | 8 +- .../newtype_retagging.tree.stderr | 8 +- .../zero-sized-protected.tree.stderr | 14 +- .../fail/data_race/dealloc_read_race1.stderr | 24 +-- .../fail/data_race/dealloc_write_race1.stderr | 24 +-- src/tools/miri/tests/fail/memleak.stderr | 14 +- .../tests/fail/memleak_no_backtrace.stderr | 2 +- src/tools/miri/tests/fail/memleak_rc.stderr | 10 +- .../deallocate_against_protector1.stderr | 8 +- .../stacked_borrows/illegal_dealloc1.stderr | 14 +- .../miri/tests/fail/tls_macro_leak.stderr | 14 +- .../miri/tests/fail/tls_static_leak.stderr | 14 +- .../tree_borrows/strongly-protected.stderr | 8 +- .../uninit/uninit_alloc_diagnostic.stderr | 2 +- ...it_alloc_diagnostic_with_provenance.stderr | 2 +- 29 files changed, 336 insertions(+), 159 deletions(-) delete mode 100644 src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr delete mode 100644 src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr delete mode 100644 src/tools/miri/tests/fail/alloc/global_system_mixup.stderr diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 958659bb5399e..f15eeb82abf29 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -12,12 +12,12 @@ use core::ptr::{self, NonNull}; extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates - // them to call `__rg_alloc` etc. if there is a `#[global_allocator]` attribute - // (the code expanding that attribute macro generates those functions), or to call + // them to call `GLOBAL.alloc` etc. if there is a `#[global_allocator]` attribute + // (the code expanding that attribute macro generates those functions), or if not // the default implementations in std (weak symbols in `library/std/src/alloc.rs`) - // otherwise. - // The rustc fork of LLVM 14 and earlier also special-cases these function names to be able to optimize them - // like `malloc`, `realloc`, and `free`, respectively. + // is used otherwise. + // The rustc fork of LLVM 14 and earlier also special-cases these function names to + // be able to optimize them like `malloc`, `realloc`, and `free`, respectively. #[rustc_allocator] #[rustc_nounwind] fn __rust_alloc(size: usize, align: usize) -> *mut u8; diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr index 3642f3f28ca2a..79a357cd541d1 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler.stderr @@ -9,7 +9,7 @@ LL | ABORT(); = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC = note: inside `std::process::abort` at RUSTLIB/std/src/process.rs:LL:CC = note: inside `std::alloc::rust_oom` at RUSTLIB/std/src/alloc.rs:LL:CC - = note: inside `std::alloc::_::__rg_oom` at RUSTLIB/std/src/alloc.rs:LL:CC + = note: inside `std::alloc::_::__rust_alloc_error_handler` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside `std::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `std::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC note: inside `main` diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr index d12e119bce3dd..2d8927d47ad90 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_custom.stderr @@ -7,7 +7,7 @@ LL | core::intrinsics::abort(); | = note: BACKTRACE: = note: inside `alloc_error_handler` at tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC -note: inside `_::__rg_oom` +note: inside `_::__rust_alloc_error_handler` --> tests/fail/alloc/alloc_error_handler_custom.rs:LL:CC | LL | #[alloc_error_handler] diff --git a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr index f495d65a8b017..e592a83c47567 100644 --- a/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr +++ b/src/tools/miri/tests/fail/alloc/alloc_error_handler_no_std.stderr @@ -9,7 +9,7 @@ LL | core::intrinsics::abort(); | = note: BACKTRACE: = note: inside `panic_handler` at tests/fail/alloc/alloc_error_handler_no_std.rs:LL:CC - = note: inside `alloc::alloc::__alloc_error_handler::__rdl_oom` at RUSTLIB/alloc/src/alloc.rs:LL:CC + = note: inside `alloc::alloc::__alloc_error_handler::__rust_alloc_error_handler` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `alloc::alloc::handle_alloc_error::rt_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC = note: inside `alloc::alloc::handle_alloc_error` at RUSTLIB/alloc/src/alloc.rs:LL:CC note: inside `start` diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr deleted file mode 100644 index f07db3c62c91d..0000000000000 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 1 and alignment ALIGN - --> tests/fail/alloc/deallocate-bad-alignment.rs:LL:CC - | -LL | dealloc(x, Layout::from_size_align_unchecked(1, 2)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 1 and alignment ALIGN - | - = 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/alloc/deallocate-bad-alignment.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 - diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr deleted file mode 100644 index c913bde04cc91..0000000000000 --- a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN - --> tests/fail/alloc/deallocate-bad-size.rs:LL:CC - | -LL | dealloc(x, Layout::from_size_align_unchecked(2, 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN - | - = 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/alloc/deallocate-bad-size.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 - diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr index 9e6ce3d45a726..344dd5689c6eb 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling - --> tests/fail/alloc/deallocate-twice.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = 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 @@ -17,7 +17,13 @@ help: ALLOC was deallocated here: LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/alloc/deallocate-twice.rs:LL:CC + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/alloc/deallocate-twice.rs:LL:CC + | +LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr deleted file mode 100644 index 4c355c511ef45..0000000000000 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error: Undefined Behavior: deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation - --> RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC - | -LL | FREE(); - | ^ deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation - | - = 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 `std::sys::alloc::PLATFORM::::dealloc` at RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC - = note: inside `::deallocate` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` - --> tests/fail/alloc/global_system_mixup.rs:LL:CC - | -LL | unsafe { System.deallocate(ptr, l) }; - | ^ - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to 1 previous error - diff --git a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr index 6f6c8850603d4..24e97383b979a 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr @@ -1,15 +1,21 @@ -error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN - --> tests/fail/alloc/reallocate-bad-size.rs:LL:CC +error: memory leaked: ALLOC (C heap, size: 1, align: 1), allocated here: + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN +LL | unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = 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/alloc/reallocate-bad-size.rs:LL:CC + = note: inside `std::sys::alloc::unix::::realloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_realloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/alloc/reallocate-bad-size.rs:LL:CC + | +LL | ... let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace +note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check + error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr index 06960380f6c94..dfe5cd024b512 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling - --> tests/fail/alloc/reallocate-dangling.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | let _z = realloc(x, Layout::from_size_align_unchecked(1, 1), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling +LL | unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = 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 @@ -17,7 +17,13 @@ help: ALLOC was deallocated here: LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/alloc/reallocate-dangling.rs:LL:CC + = note: inside `std::sys::alloc::unix::::realloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_realloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/alloc/reallocate-dangling.rs:LL:CC + | +LL | let _z = realloc(x, Layout::from_size_align_unchecked(1, 1), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/stack_free.stderr b/src/tools/miri/tests/fail/alloc/stack_free.stderr index 7d7cee133c653..2885151e7113f 100644 --- a/src/tools/miri/tests/fail/alloc/stack_free.stderr +++ b/src/tools/miri/tests/fail/alloc/stack_free.stderr @@ -1,12 +1,14 @@ -error: Undefined Behavior: deallocating ALLOC, which is stack variable memory, using Rust heap deallocation operation - --> RUSTLIB/alloc/src/boxed.rs:LL:CC +error: Undefined Behavior: deallocating ALLOC, which is stack variable memory, using C heap deallocation operation + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | self.1.deallocate(From::from(ptr.cast()), layout); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating ALLOC, which is stack variable memory, using Rust heap deallocation operation +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating ALLOC, which is stack variable memory, using C heap deallocation operation | = 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 `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/alloc/too_large.stderr b/src/tools/miri/tests/fail/alloc/too_large.stderr index 03e54088e3b50..3a3c239261903 100644 --- a/src/tools/miri/tests/fail/alloc/too_large.stderr +++ b/src/tools/miri/tests/fail/alloc/too_large.stderr @@ -1,13 +1,29 @@ -error: Undefined Behavior: creating an allocation larger than half the address space - --> tests/fail/alloc/too_large.rs:LL:CC +thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: +unsafe precondition(s) violated: Layout::from_size_align_unchecked requires that align is a power of 2 and the rounded-up allocation size does not exceed isize::MAX +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect +thread caused non-unwinding panic. aborting. +error: abnormal termination: the program aborted execution + --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC | -LL | __rust_alloc(bytes, 1); - | ^^^^^^^^^^^^^^^^^^^^^^ creating an allocation larger than half the address space +LL | unsafe { libc::abort() } + | ^^^^^^^^^^^^^ the program aborted execution | - = 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/alloc/too_large.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC + = note: inside `std::alloc::Layout::from_size_align_unchecked::precondition_check` at RUSTLIB/core/src/ub_checks.rs:LL:CC + = note: inside `std::alloc::Layout::from_size_align_unchecked` at RUSTLIB/core/src/ub_checks.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/alloc/too_large.rs:LL:CC + | +LL | __rust_alloc(bytes, 1); + | ^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr index 8eb71f5ce8459..4bbda6c4ed846 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr @@ -1,14 +1,138 @@ -error: unsupported operation: creating allocation with alignment ALIGN exceeding rustc's maximum supported value - --> tests/fail/alloc/unsupported_big_alignment.rs:LL:CC +thread 'rustc' panicked at src/tools/miri/src/shims/alloc.rs:LL:CC: +called `Result::unwrap()` on an `Err` value: `1073741824` is too large +stack backtrace: + 0: rust_begin_unwind + at RUSTLIB/std/src/panicking.rs:LL:CC + 1: core::panicking::panic_fmt + at RUSTLIB/core/src/panicking.rs:LL:CC + 2: core::result::unwrap_failed + at RUSTLIB/core/src/result.rs:LL:CC + 3: >::unwrap + at RUSTLIB/core/src/result.rs:LL:CC + 4: as miri::shims::alloc::EvalContextExt>::posix_memalign + at ./src/shims/alloc.rs:LL:CC + 5: as miri::shims::unix::foreign_items::EvalContextExt>::emulate_foreign_item_inner + at ./src/shims/unix/foreign_items.rs:LL:CC + 6: as miri::shims::foreign_items::EvalContextExtPriv>::emulate_foreign_item_inner + at ./src/shims/foreign_items.rs:LL:CC + 7: as miri::shims::foreign_items::EvalContextExt>::emulate_foreign_item + at ./src/shims/foreign_items.rs:LL:CC + 8: ::find_mir_or_eval_fn + at ./src/machine.rs:LL:CC + 9: >::init_fn_call + at /home/gh-bjorn3/rust/compiler/rustc_const_eval/src/interpret/call.rs:LL:CC + 10: >::eval_terminator + at /home/gh-bjorn3/rust/compiler/rustc_const_eval/src/interpret/step.rs:LL:CC + 11: >::step + at /home/gh-bjorn3/rust/compiler/rustc_const_eval/src/interpret/step.rs:LL:CC + 12: as miri::concurrency::thread::EvalContextExt>::run_threads + at ./src/concurrency/thread.rs:LL:CC + 13: miri::eval::eval_entry::{closure#0} + at ./src/eval.rs:LL:CC + 14: >::call_once + at RUSTLIB/core/src/ops/function.rs:LL:CC + 15: as core::ops::function::FnOnce<()>>::call_once + at RUSTLIB/core/src/panic/unwind_safe.rs:LL:CC + 16: std::panicking::try::do_call + at RUSTLIB/std/src/panicking.rs:LL:CC + 17: std::panicking::try + at RUSTLIB/std/src/panicking.rs:LL:CC + 18: std::panic::catch_unwind + at RUSTLIB/std/src/panic.rs:LL:CC + 19: miri::eval::eval_entry + at ./src/eval.rs:LL:CC + 20: ::after_analysis + at ./src/bin/miri.rs:LL:CC + 21: rustc_driver_impl::run_compiler::{closure#0}::{closure#2} + at /home/gh-bjorn3/rust/compiler/rustc_driver_impl/src/lib.rs:LL:CC + 22: rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure#0} + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/passes.rs:LL:CC + 23: ::create_global_ctxt::{closure#3} + at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context.rs:LL:CC + 24: rustc_middle::ty::context::tls::enter_context::{closure#0} + at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context/tls.rs:LL:CC + 25: >>::try_with + at RUSTLIB/std/src/thread/local.rs:LL:CC + 26: >>::with + at RUSTLIB/std/src/thread/local.rs:LL:CC + 27: rustc_middle::ty::context::tls::enter_context + at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context/tls.rs:LL:CC + 28: ::create_global_ctxt + at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context.rs:LL:CC + 29: rustc_interface::passes::create_and_enter_global_ctxt::{closure#2} + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/passes.rs:LL:CC + 30: , rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2} as core::ops::function::FnOnce<(&rustc_interface::interface::Compiler, &std::sync::once_lock::OnceLock, &rustc_data_structures::sync::worker_local::WorkerLocal, &rustc_data_structures::sync::worker_local::WorkerLocal, rustc_driver_impl::run_compiler::{closure#0}::{closure#2})>>::call_once::{shim:vtable#0} + at RUSTLIB/core/src/ops/function.rs:LL:CC + 31: core::ops::function::FnOnce<(&'a rustc_interface::interface::Compiler, &'a std::sync::once_lock::OnceLock>, &'a rustc_data_structures::sync::worker_local::WorkerLocal>, &'a rustc_data_structures::sync::worker_local::WorkerLocal>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}), Output = core::option::Option>> as core::ops::function::FnOnce<(&rustc_interface::interface::Compiler, &std::sync::once_lock::OnceLock, &rustc_data_structures::sync::worker_local::WorkerLocal, &rustc_data_structures::sync::worker_local::WorkerLocal, rustc_driver_impl::run_compiler::{closure#0}::{closure#2})>>::call_once + at RUSTLIB/alloc/src/boxed.rs:LL:CC + 32: rustc_interface::passes::create_and_enter_global_ctxt + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/passes.rs:LL:CC + 33: rustc_driver_impl::run_compiler::{closure#0} + at /home/gh-bjorn3/rust/compiler/rustc_driver_impl/src/lib.rs:LL:CC + 34: rustc_interface::interface::run_compiler::{closure#1}::{closure#0} + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/interface.rs:LL:CC + 35: ::{closure#1}::{closure#0}> as core::ops::function::FnOnce<()>>::call_once + at RUSTLIB/core/src/panic/unwind_safe.rs:LL:CC + 36: std::panicking::try::do_call + at RUSTLIB/std/src/panicking.rs:LL:CC + 37: std::panicking::try + at RUSTLIB/std/src/panicking.rs:LL:CC + 38: std::panic::catch_unwind + at RUSTLIB/std/src/panic.rs:LL:CC + 39: rustc_interface::interface::run_compiler::{closure#1} + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/interface.rs:LL:CC + 40: rustc_interface::util::run_in_thread_pool_with_globals::{closure#0} + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/util.rs:LL:CC + 41: rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure#0} + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/util.rs:LL:CC + 42: >::set + at CARGO_REGISTRY/.../lib.rs:LL:CC + 43: rustc_span::create_session_globals_then + at /home/gh-bjorn3/rust/compiler/rustc_span/src/lib.rs:LL:CC + 44: rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0} + at /home/gh-bjorn3/rust/compiler/rustc_interface/src/util.rs:LL:CC +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. + +error: the compiler unexpectedly panicked. this is a bug. + +note: we would appreciate a bug report: https://github.com/rust-lang/miri/issues/new + +note: please make sure that you have updated to the latest nightly + +note: please attach the file at `/home/gh-bjorn3/rust/src/tools/miri/rustc-ice-2024-12-20T10_31_46-710436.txt` to your bug report + +note: compiler flags: -Z ui-testing + +query stack during panic: +end of query stack + +Miri caused an ICE during evaluation. Here's the interpreter backtrace at the time of the panic: +note: the place in the program where the ICE was triggered + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | __rust_alloc(1, 1 << 30); - | ^^^^^^^^^^^^^^^^^^^^^^^^ creating allocation with alignment ALIGN exceeding rustc's maximum supported value +LL | let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support = note: BACKTRACE: - = note: inside `main` at tests/fail/alloc/unsupported_big_alignment.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 + = note: inside `std::sys::alloc::unix::aligned_malloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/alloc/unsupported_big_alignment.rs:LL:CC + | +LL | __rust_alloc(1, 1 << 30); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `>::call_once - shim(fn())` at RUSTLIB/core/src/ops/function.rs:LL:CC + = note: inside `std::sys::backtrace::__rust_begin_short_backtrace::` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at RUSTLIB/core/src/ops/function.rs:LL:CC + = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panicking::r#try:: i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panic.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panicking::r#try::` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC + = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC + = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC diff --git a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr index 0a36d3d58b616..b7cc9f1a64904 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr @@ -1,13 +1,29 @@ -error: Undefined Behavior: creating allocation with non-power-of-two alignment ALIGN - --> tests/fail/alloc/unsupported_non_power_two_alignment.rs:LL:CC +thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: +unsafe precondition(s) violated: Layout::from_size_align_unchecked requires that align is a power of 2 and the rounded-up allocation size does not exceed isize::MAX +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect +thread caused non-unwinding panic. aborting. +error: abnormal termination: the program aborted execution + --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC | -LL | __rust_alloc(1, 3); - | ^^^^^^^^^^^^^^^^^^ creating allocation with non-power-of-two alignment ALIGN +LL | unsafe { libc::abort() } + | ^^^^^^^^^^^^^ the program aborted execution | - = 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/alloc/unsupported_non_power_two_alignment.rs:LL:CC + = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC + = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC + = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC + = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC + = note: inside `std::alloc::Layout::from_size_align_unchecked::precondition_check` at RUSTLIB/core/src/ub_checks.rs:LL:CC + = note: inside `std::alloc::Layout::from_size_align_unchecked` at RUSTLIB/core/src/ub_checks.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/alloc/unsupported_non_power_two_alignment.rs:LL:CC + | +LL | __rust_alloc(1, 3); + | ^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr index ef1aa74ddf4ba..5e49ef214095a 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden - --> RUSTLIB/alloc/src/boxed.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | self.1.deallocate(From::from(ptr.cast()), layout); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) @@ -25,6 +25,8 @@ LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit = note: BACKTRACE (of the first span): + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr index 28fcd1411f962..4b264a73dff6b 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden - --> RUSTLIB/alloc/src/boxed.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | self.1.deallocate(From::from(ptr.cast()), layout); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) @@ -25,6 +25,8 @@ LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit = note: BACKTRACE (of the first span): + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr index 18d1fb6939540..48e84a8b04900 100644 --- a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through (root of the allocation) at ALLOC[0x0] is forbidden - --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | unsafe { dealloc(ptr, l) }; - | ^^^^^^^^^^^^^^^ deallocation through (root of the allocation) at ALLOC[0x0] is forbidden +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through (root of the allocation) at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the allocation of the accessed tag (root of the allocation) also contains the strongly protected tag @@ -18,7 +18,13 @@ help: the strongly protected tag was created here, in the initial state Re LL | fn test(_x: &mut (), ptr: *mut u8, l: Layout) { | ^^ = note: BACKTRACE (of the first span): - = note: inside `test` at tests/fail/both_borrows/zero-sized-protected.rs:LL:CC + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `test` + --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC + | +LL | unsafe { dealloc(ptr, l) }; + | ^^^^^^^^^^^^^^^ note: inside `main` --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC | diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr index 8eb4ebbcf729d..767a08e48de0f 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr @@ -1,13 +1,8 @@ error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here - --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | / __rust_dealloc( -LL | | -LL | | ptr.0 as *mut _, -LL | | std::mem::size_of::(), -LL | | std::mem::align_of::(), -LL | | ); - | |_____________^ Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here | help: and (1) occurred earlier here --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC @@ -17,7 +12,18 @@ LL | let _val = *ptr.0; = 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 (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_read_race1.rs:LL:CC + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside closure + --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC + | +LL | / __rust_dealloc( +LL | | +LL | | ptr.0 as *mut _, +LL | | std::mem::size_of::(), +LL | | std::mem::align_of::(), +LL | | ); + | |_____________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr index 48d974241aada..9b9e3e40fe5a4 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr @@ -1,13 +1,8 @@ error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here - --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | / __rust_dealloc( -LL | | -LL | | ptr.0 as *mut _, -LL | | std::mem::size_of::(), -LL | | std::mem::align_of::(), -LL | | ); - | |_____________^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here | help: and (1) occurred earlier here --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC @@ -17,7 +12,18 @@ LL | *ptr.0 = 2; = 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 (of the first span) on thread `unnamed-ID`: - = note: inside closure at tests/fail/data_race/dealloc_write_race1.rs:LL:CC + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside closure + --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC + | +LL | / __rust_dealloc( +LL | | +LL | | ptr.0 as *mut _, +LL | | std::mem::size_of::(), +LL | | std::mem::align_of::(), +LL | | ); + | |_____________^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/memleak.stderr b/src/tools/miri/tests/fail/memleak.stderr index 89db0f1eb1628..b73b79cba1bb7 100644 --- a/src/tools/miri/tests/fail/memleak.stderr +++ b/src/tools/miri/tests/fail/memleak.stderr @@ -1,11 +1,17 @@ -error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: +error: memory leaked: ALLOC (C heap, size: 4, align: 4), allocated here: + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + | +LL | unsafe { libc::malloc(layout.size()) as *mut u8 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: BACKTRACE: + = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` --> tests/fail/memleak.rs:LL:CC | LL | std::mem::forget(Box::new(42)); | ^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `main` at tests/fail/memleak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr index 6850928e1503c..5b9f73f5c61e7 100644 --- a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr +++ b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr @@ -1,4 +1,4 @@ -error: memory leaked: ALLOC (Rust heap, size: 4, align: 4) +error: memory leaked: ALLOC (C heap, size: 4, align: 4) note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check diff --git a/src/tools/miri/tests/fail/memleak_rc.stderr b/src/tools/miri/tests/fail/memleak_rc.stderr index df12eeed6ac64..07e4cf2bd5eb1 100644 --- a/src/tools/miri/tests/fail/memleak_rc.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.stderr @@ -1,10 +1,12 @@ -error: memory leaked: ALLOC (Rust heap, SIZE, ALIGN), allocated here: - --> RUSTLIB/alloc/src/rc.rs:LL:CC +error: memory leaked: ALLOC (C heap, size: 32, align: 16), allocated here: + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value })) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { libc::malloc(layout.size()) as *mut u8 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: BACKTRACE: + = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside `std::rc::Rc::>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC note: inside `main` --> tests/fail/memleak_rc.rs:LL:CC diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr index f4cfa49c1564e..5dd163ca5facf 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr @@ -1,12 +1,14 @@ error: Undefined Behavior: deallocating while item [Unique for ] is strongly protected - --> RUSTLIB/alloc/src/boxed.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | self.1.deallocate(From::from(ptr.cast()), layout); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [Unique for ] is strongly protected +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [Unique for ] is strongly protected | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information = note: BACKTRACE: + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr index ddf8dbea31f59..7459ffc9fba47 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: attempting deallocation using at ALLOC, but that tag does not exist in the borrow stack for this location - --> tests/fail/stacked_borrows/illegal_deALLOC.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | dealloc(ptr2, Layout::from_size_align_unchecked(1, 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempting deallocation using at ALLOC, but that tag does not exist in the borrow stack for this location +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempting deallocation using at ALLOC, but that tag does not exist in the borrow stack for this location | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -17,7 +17,13 @@ help: was later invalidated at offsets [0x0..0x1] by a write access LL | ptr1.write(0); | ^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `main` at tests/fail/stacked_borrows/illegal_deALLOC.rs:LL:CC + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/stacked_borrows/illegal_deALLOC.rs:LL:CC + | +LL | dealloc(ptr2, Layout::from_size_align_unchecked(1, 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tls_macro_leak.stderr b/src/tools/miri/tests/fail/tls_macro_leak.stderr index 512932b3cb8a6..caac06ff4e4e9 100644 --- a/src/tools/miri/tests/fail/tls_macro_leak.stderr +++ b/src/tools/miri/tests/fail/tls_macro_leak.stderr @@ -1,11 +1,17 @@ -error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: +error: memory leaked: ALLOC (C heap, size: 4, align: 4), allocated here: + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + | +LL | unsafe { libc::malloc(layout.size()) as *mut u8 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: BACKTRACE: + = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside closure --> tests/fail/tls_macro_leak.rs:LL:CC | LL | cell.set(Some(Box::leak(Box::new(123)))); | ^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside closure at tests/fail/tls_macro_leak.rs:LL:CC = note: inside `std::thread::LocalKey::>>::try_with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC = note: inside `std::thread::LocalKey::>>::with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC note: inside closure diff --git a/src/tools/miri/tests/fail/tls_static_leak.stderr b/src/tools/miri/tests/fail/tls_static_leak.stderr index 24306cca7ffdd..946a2927f67a8 100644 --- a/src/tools/miri/tests/fail/tls_static_leak.stderr +++ b/src/tools/miri/tests/fail/tls_static_leak.stderr @@ -1,11 +1,17 @@ -error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: +error: memory leaked: ALLOC (C heap, size: 4, align: 4), allocated here: + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + | +LL | unsafe { libc::malloc(layout.size()) as *mut u8 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: BACKTRACE: + = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside closure --> tests/fail/tls_static_leak.rs:LL:CC | LL | TLS.set(Some(Box::leak(Box::new(123)))); | ^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside closure at tests/fail/tls_static_leak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr index f6197a2acb391..f7066853827e8 100644 --- a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden - --> RUSTLIB/alloc/src/boxed.rs:LL:CC + --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC | -LL | self.1.deallocate(From::from(ptr.cast()), layout); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden +LL | unsafe { libc::free(ptr as *mut libc::c_void) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the allocation of the accessed tag also contains the strongly protected tag @@ -18,6 +18,8 @@ help: the strongly protected tag was created here, in the initial state Re LL | fn inner(x: &mut i32, f: fn(*mut i32)) { | ^ = note: BACKTRACE (of the first span): + = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr index 0996e5d11eff6..420b4e051affd 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr @@ -16,7 +16,7 @@ LL | drop(slice1.cmp(slice2)); | ^^^^^^^^^^^^^^^^^^ Uninitialized memory occurred at ALLOC[0x4..0x10], in this allocation: -ALLOC (Rust heap, size: 32, align: 8) { +ALLOC (C heap, size: 32, align: 16) { 0x00 │ 41 42 43 44 __ __ __ __ __ __ __ __ __ __ __ __ │ ABCD░░░░░░░░░░░░ 0x10 │ 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ .░░░░░░░░░░░░░░░ } diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr index bcde9377c5400..59aae23a66c21 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr @@ -16,7 +16,7 @@ LL | drop(slice1.cmp(slice2)); | ^^^^^^^^^^^^^^^^^^ Uninitialized memory occurred at ALLOC[0x4..0x8], in this allocation: -ALLOC (Rust heap, size: 16, align: 8) { +ALLOC (C heap, size: 16, align: 16) { ╾42[ALLOC] (1 ptr byte)╼ 12 13 ╾43[ALLOC] (1 ptr byte)╼ __ __ __ __ __ __ __ __ __ __ __ __ │ ━..━░░░░░░░░░░░░ } ALLOC (global (static or const), size: 1, align: 1) { From 48ec50dea06081abb8f29fdcbb3133de9d5da632 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:02:11 +0000 Subject: [PATCH 5/8] Provide a default for __rust_alloc_error_handler_should_panic --- library/alloc/src/alloc.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index f15eeb82abf29..d3d329ba51ff8 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -357,7 +357,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg(not(no_global_oom_handling))] extern "Rust" { // This is the magic symbol to call the global alloc error handler. rustc generates - // it if there is a `#[alloc_error_handler]`, or to the weak implementations below + // it if there is an `#[alloc_error_handler]`, or to the weak implementations below // is called otherwise. fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } @@ -425,13 +425,16 @@ pub mod __alloc_error_handler { #[rustc_std_internal_symbol] #[linkage = "weak"] pub unsafe extern "Rust" fn __rust_alloc_error_handler(size: usize, _align: usize) -> ! { - extern "Rust" { - // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. - static __rust_alloc_error_handler_should_panic: u8; - } - - if unsafe { __rust_alloc_error_handler_should_panic != 0 } { + // This symbol is normally overwritten by rustc next to __rust_alloc_error_handler. + // However when skipping the allocator handler shim the value here is used which + // corresponds to -Zoom=abort. + // Its value depends on the -Zoom={panic,abort} compiler option. + #[rustc_std_internal_symbol] + #[linkage = "weak"] + #[allow(non_upper_case_globals)] + static __rust_alloc_error_handler_should_panic: u8 = 0; + + if __rust_alloc_error_handler_should_panic != 0 { panic!("memory allocation of {size} bytes failed") } else { core::panicking::panic_nounwind_fmt( From 6a563c92f9541fa6b9e4ef73a517f4bf69e491a0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:27:37 +0000 Subject: [PATCH 6/8] Revert some miri changes --- src/tools/miri/src/helpers.rs | 15 ++ src/tools/miri/src/shims/alloc.rs | 29 ++++ src/tools/miri/src/shims/foreign_items.rs | 136 ++++++++++++++--- .../alloc/deallocate-bad-alignment.stderr | 15 ++ .../fail/alloc/deallocate-bad-size.stderr | 15 ++ .../tests/fail/alloc/deallocate-twice.stderr | 14 +- .../fail/alloc/global_system_mixup.stderr | 21 +++ .../fail/alloc/reallocate-bad-size.stderr | 20 +-- .../fail/alloc/reallocate-dangling.stderr | 14 +- .../miri/tests/fail/alloc/stack_free.stderr | 10 +- .../miri/tests/fail/alloc/too_large.stderr | 30 +--- .../alloc/unsupported_big_alignment.stderr | 144 ++---------------- ...unsupported_non_power_two_alignment.stderr | 30 +--- .../newtype_pair_retagging.tree.stderr | 8 +- .../newtype_retagging.tree.stderr | 8 +- .../zero-sized-protected.tree.stderr | 14 +- .../fail/data_race/dealloc_read_race1.stderr | 24 ++- .../fail/data_race/dealloc_write_race1.stderr | 24 ++- src/tools/miri/tests/fail/memleak.stderr | 14 +- .../tests/fail/memleak_no_backtrace.stderr | 2 +- src/tools/miri/tests/fail/memleak_rc.stderr | 10 +- .../deallocate_against_protector1.stderr | 8 +- .../stacked_borrows/illegal_dealloc1.stderr | 14 +- .../miri/tests/fail/tls_macro_leak.stderr | 14 +- .../miri/tests/fail/tls_static_leak.stderr | 14 +- .../tree_borrows/strongly-protected.stderr | 8 +- .../uninit/uninit_alloc_diagnostic.stderr | 2 +- ...it_alloc_diagnostic_with_provenance.stderr | 2 +- 28 files changed, 309 insertions(+), 350 deletions(-) create mode 100644 src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr create mode 100644 src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr create mode 100644 src/tools/miri/tests/fail/alloc/global_system_mixup.stderr diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index adfec33beac60..28cf3f105d1eb 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -960,6 +960,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { return interp_ok(()); } + if ["__rust_alloc", "__rust_alloc_zeroed", "__rust_realloc", "__rust_dealloc"] + .contains(&link_name.as_str()) + { + let attrs = self.eval_context_ref().tcx.codegen_fn_attrs(instance.def_id()); + if attrs + .linkage + .map_or(false, |linkage| linkage == rustc_middle::mir::mono::Linkage::WeakAny) + && attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + { + // We intentionally intercept the allocator methods even though libstd provides + // default implementations. + return interp_ok(()); + } + } + throw_machine_stop!(TerminationInfo::SymbolShimClashing { link_name, span: body.span.data(), diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs index 4dc9ba354a05a..25c0b52d0618b 100644 --- a/src/tools/miri/src/shims/alloc.rs +++ b/src/tools/miri/src/shims/alloc.rs @@ -1,6 +1,7 @@ use std::iter; use rustc_abi::{Align, Size}; +use rustc_ast::expand::allocator::AllocatorKind; use crate::*; @@ -51,6 +52,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { Align::from_bytes(prev_power_of_two(size)).unwrap() } + /// Emulates calling the internal __rust_* allocator functions + fn emulate_allocator( + &mut self, + default: impl FnOnce(&mut MiriInterpCx<'tcx>) -> InterpResult<'tcx>, + ) -> InterpResult<'tcx, EmulateItemResult> { + let this = self.eval_context_mut(); + + let Some(allocator_kind) = this.tcx.allocator_kind(()) else { + // in real code, this symbol does not exist without an allocator + return interp_ok(EmulateItemResult::NotSupported); + }; + + match allocator_kind { + AllocatorKind::Global => { + // When `#[global_allocator]` is used, `__rust_*` is defined by the macro expansion + // of this attribute. As such we have to call an exported Rust function, + // and not execute any Miri shim. Somewhat unintuitively doing so is done + // by returning `NotSupported`, which triggers the `lookup_exported_symbol` + // fallback case in `emulate_foreign_item`. + interp_ok(EmulateItemResult::NotSupported) + } + AllocatorKind::Default => { + default(this)?; + interp_ok(EmulateItemResult::NeedsReturn) + } + } + } + fn malloc(&mut self, size: u64, zero_init: bool) -> InterpResult<'tcx, Pointer> { let this = self.eval_context_mut(); let align = this.malloc_align(size); diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 0970d768f8b58..f1497af4a7f53 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -1,5 +1,6 @@ use std::collections::hash_map::Entry; use std::io::Write; +use std::iter; use std::path::Path; use rustc_abi::{Align, AlignFromBytesError, Size}; @@ -501,33 +502,124 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } // Rust allocation - "miri_alloc" => { - let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; - let size = this.read_target_usize(size)?; - let align = this.read_target_usize(align)?; + "__rust_alloc" | "miri_alloc" => { + let default = |ecx: &mut MiriInterpCx<'tcx>| { + // Only call `check_shim` when `#[global_allocator]` isn't used. When that + // macro is used, we act like no shim exists, so that the exported function can run. + let [size, align] = ecx.check_shim(abi, Conv::Rust, link_name, args)?; + let size = ecx.read_target_usize(size)?; + let align = ecx.read_target_usize(align)?; + + ecx.check_rustc_alloc_request(size, align)?; + + let memory_kind = match link_name.as_str() { + "__rust_alloc" => MiriMemoryKind::Rust, + "miri_alloc" => MiriMemoryKind::Miri, + _ => unreachable!(), + }; - this.check_rustc_alloc_request(size, align)?; + let ptr = ecx.allocate_ptr( + Size::from_bytes(size), + Align::from_bytes(align).unwrap(), + memory_kind.into(), + )?; - let ptr = this.allocate_ptr( - Size::from_bytes(size), - Align::from_bytes(align).unwrap(), - MiriMemoryKind::Miri.into(), - )?; + ecx.write_pointer(ptr, dest) + }; - this.write_pointer(ptr, dest)?; + match link_name.as_str() { + "__rust_alloc" => return this.emulate_allocator(default), + "miri_alloc" => { + default(this)?; + return interp_ok(EmulateItemResult::NeedsReturn); + } + _ => unreachable!(), + } } - "miri_dealloc" => { - let [ptr, old_size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; - let ptr = this.read_pointer(ptr)?; - let old_size = this.read_target_usize(old_size)?; - let align = this.read_target_usize(align)?; + "__rust_alloc_zeroed" => { + return this.emulate_allocator(|this| { + // See the comment for `__rust_alloc` why `check_shim` is only called in the + // default case. + let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?; + let size = this.read_target_usize(size)?; + let align = this.read_target_usize(align)?; - // No need to check old_size/align; we anyway check that they match the allocation. - this.deallocate_ptr( - ptr, - Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())), - MiriMemoryKind::Miri.into(), - )?; + this.check_rustc_alloc_request(size, align)?; + + let ptr = this.allocate_ptr( + Size::from_bytes(size), + Align::from_bytes(align).unwrap(), + MiriMemoryKind::Rust.into(), + )?; + + // We just allocated this, the access is definitely in-bounds. + this.write_bytes_ptr( + ptr.into(), + iter::repeat(0u8).take(usize::try_from(size).unwrap()), + ) + .unwrap(); + this.write_pointer(ptr, dest) + }); + } + "__rust_dealloc" | "miri_dealloc" => { + let default = |ecx: &mut MiriInterpCx<'tcx>| { + // See the comment for `__rust_alloc` why `check_shim` is only called in the + // default case. + let [ptr, old_size, align] = + ecx.check_shim(abi, Conv::Rust, link_name, args)?; + let ptr = ecx.read_pointer(ptr)?; + let old_size = ecx.read_target_usize(old_size)?; + let align = ecx.read_target_usize(align)?; + + let memory_kind = match link_name.as_str() { + "__rust_dealloc" => MiriMemoryKind::Rust, + "miri_dealloc" => MiriMemoryKind::Miri, + _ => unreachable!(), + }; + + // No need to check old_size/align; we anyway check that they match the allocation. + ecx.deallocate_ptr( + ptr, + Some((Size::from_bytes(old_size), Align::from_bytes(align).unwrap())), + memory_kind.into(), + ) + }; + + match link_name.as_str() { + "__rust_dealloc" => { + return this.emulate_allocator(default); + } + "miri_dealloc" => { + default(this)?; + return interp_ok(EmulateItemResult::NeedsReturn); + } + _ => unreachable!(), + } + } + "__rust_realloc" => { + return this.emulate_allocator(|this| { + // See the comment for `__rust_alloc` why `check_shim` is only called in the + // default case. + let [ptr, old_size, align, new_size] = + this.check_shim(abi, Conv::Rust, link_name, args)?; + let ptr = this.read_pointer(ptr)?; + let old_size = this.read_target_usize(old_size)?; + let align = this.read_target_usize(align)?; + let new_size = this.read_target_usize(new_size)?; + // No need to check old_size; we anyway check that they match the allocation. + + this.check_rustc_alloc_request(new_size, align)?; + + let align = Align::from_bytes(align).unwrap(); + let new_ptr = this.reallocate_ptr( + ptr, + Some((Size::from_bytes(old_size), align)), + Size::from_bytes(new_size), + align, + MiriMemoryKind::Rust.into(), + )?; + this.write_pointer(new_ptr, dest) + }); } // C memory handling functions diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr new file mode 100644 index 0000000000000..f07db3c62c91d --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 1 and alignment ALIGN + --> tests/fail/alloc/deallocate-bad-alignment.rs:LL:CC + | +LL | dealloc(x, Layout::from_size_align_unchecked(1, 2)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 1 and alignment ALIGN + | + = 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/alloc/deallocate-bad-alignment.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 + diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr new file mode 100644 index 0000000000000..c913bde04cc91 --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN + --> tests/fail/alloc/deallocate-bad-size.rs:LL:CC + | +LL | dealloc(x, Layout::from_size_align_unchecked(2, 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN + | + = 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/alloc/deallocate-bad-size.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 + diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr index 344dd5689c6eb..9e6ce3d45a726 100644 --- a/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr +++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> tests/fail/alloc/deallocate-twice.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling +LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = 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 @@ -17,13 +17,7 @@ help: ALLOC was deallocated here: LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` - --> tests/fail/alloc/deallocate-twice.rs:LL:CC - | -LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `main` at tests/fail/alloc/deallocate-twice.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr new file mode 100644 index 0000000000000..4c355c511ef45 --- /dev/null +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.stderr @@ -0,0 +1,21 @@ +error: Undefined Behavior: deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation + --> RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC + | +LL | FREE(); + | ^ deallocating ALLOC, which is Rust heap memory, using PLATFORM heap deallocation operation + | + = 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 `std::sys::alloc::PLATFORM::::dealloc` at RUSTLIB/std/src/sys/alloc/PLATFORM.rs:LL:CC + = note: inside `::deallocate` at RUSTLIB/std/src/alloc.rs:LL:CC +note: inside `main` + --> tests/fail/alloc/global_system_mixup.rs:LL:CC + | +LL | unsafe { System.deallocate(ptr, l) }; + | ^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr index 24e97383b979a..6f6c8850603d4 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.stderr @@ -1,21 +1,15 @@ -error: memory leaked: ALLOC (C heap, size: 1, align: 1), allocated here: - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC +error: Undefined Behavior: incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN + --> tests/fail/alloc/reallocate-bad-size.rs:LL:CC | -LL | unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: ALLOC has size 1 and alignment ALIGN, but gave size 2 and alignment ALIGN | + = 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 `std::sys::alloc::unix::::realloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_realloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` - --> tests/fail/alloc/reallocate-bad-size.rs:LL:CC - | -LL | ... let _y = realloc(x, Layout::from_size_align_unchecked(2, 1), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `main` at tests/fail/alloc/reallocate-bad-size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check - error: aborting due to 1 previous error diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr index dfe5cd024b512..06960380f6c94 100644 --- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr +++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> tests/fail/alloc/reallocate-dangling.rs:LL:CC | -LL | unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling +LL | let _z = realloc(x, Layout::from_size_align_unchecked(1, 1), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = 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 @@ -17,13 +17,7 @@ help: ALLOC was deallocated here: LL | dealloc(x, Layout::from_size_align_unchecked(1, 1)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `std::sys::alloc::unix::::realloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_realloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` - --> tests/fail/alloc/reallocate-dangling.rs:LL:CC - | -LL | let _z = realloc(x, Layout::from_size_align_unchecked(1, 1), 1); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `main` at tests/fail/alloc/reallocate-dangling.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/stack_free.stderr b/src/tools/miri/tests/fail/alloc/stack_free.stderr index 2885151e7113f..7d7cee133c653 100644 --- a/src/tools/miri/tests/fail/alloc/stack_free.stderr +++ b/src/tools/miri/tests/fail/alloc/stack_free.stderr @@ -1,14 +1,12 @@ -error: Undefined Behavior: deallocating ALLOC, which is stack variable memory, using C heap deallocation operation - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC +error: Undefined Behavior: deallocating ALLOC, which is stack variable memory, using Rust heap deallocation operation + --> RUSTLIB/alloc/src/boxed.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating ALLOC, which is stack variable memory, using C heap deallocation operation +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating ALLOC, which is stack variable memory, using Rust heap deallocation operation | = 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 `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/alloc/too_large.stderr b/src/tools/miri/tests/fail/alloc/too_large.stderr index 3a3c239261903..03e54088e3b50 100644 --- a/src/tools/miri/tests/fail/alloc/too_large.stderr +++ b/src/tools/miri/tests/fail/alloc/too_large.stderr @@ -1,29 +1,13 @@ -thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: -unsafe precondition(s) violated: Layout::from_size_align_unchecked requires that align is a power of 2 and the rounded-up allocation size does not exceed isize::MAX -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect -thread caused non-unwinding panic. aborting. -error: abnormal termination: the program aborted execution - --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - | -LL | unsafe { libc::abort() } - | ^^^^^^^^^^^^^ the program aborted execution - | - = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `std::alloc::Layout::from_size_align_unchecked::precondition_check` at RUSTLIB/core/src/ub_checks.rs:LL:CC - = note: inside `std::alloc::Layout::from_size_align_unchecked` at RUSTLIB/core/src/ub_checks.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` +error: Undefined Behavior: creating an allocation larger than half the address space --> tests/fail/alloc/too_large.rs:LL:CC | LL | __rust_alloc(bytes, 1); - | ^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ creating an allocation larger than half the address space + | + = 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/alloc/too_large.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr index 4bbda6c4ed846..8eb71f5ce8459 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_big_alignment.stderr @@ -1,138 +1,14 @@ -thread 'rustc' panicked at src/tools/miri/src/shims/alloc.rs:LL:CC: -called `Result::unwrap()` on an `Err` value: `1073741824` is too large -stack backtrace: - 0: rust_begin_unwind - at RUSTLIB/std/src/panicking.rs:LL:CC - 1: core::panicking::panic_fmt - at RUSTLIB/core/src/panicking.rs:LL:CC - 2: core::result::unwrap_failed - at RUSTLIB/core/src/result.rs:LL:CC - 3: >::unwrap - at RUSTLIB/core/src/result.rs:LL:CC - 4: as miri::shims::alloc::EvalContextExt>::posix_memalign - at ./src/shims/alloc.rs:LL:CC - 5: as miri::shims::unix::foreign_items::EvalContextExt>::emulate_foreign_item_inner - at ./src/shims/unix/foreign_items.rs:LL:CC - 6: as miri::shims::foreign_items::EvalContextExtPriv>::emulate_foreign_item_inner - at ./src/shims/foreign_items.rs:LL:CC - 7: as miri::shims::foreign_items::EvalContextExt>::emulate_foreign_item - at ./src/shims/foreign_items.rs:LL:CC - 8: ::find_mir_or_eval_fn - at ./src/machine.rs:LL:CC - 9: >::init_fn_call - at /home/gh-bjorn3/rust/compiler/rustc_const_eval/src/interpret/call.rs:LL:CC - 10: >::eval_terminator - at /home/gh-bjorn3/rust/compiler/rustc_const_eval/src/interpret/step.rs:LL:CC - 11: >::step - at /home/gh-bjorn3/rust/compiler/rustc_const_eval/src/interpret/step.rs:LL:CC - 12: as miri::concurrency::thread::EvalContextExt>::run_threads - at ./src/concurrency/thread.rs:LL:CC - 13: miri::eval::eval_entry::{closure#0} - at ./src/eval.rs:LL:CC - 14: >::call_once - at RUSTLIB/core/src/ops/function.rs:LL:CC - 15: as core::ops::function::FnOnce<()>>::call_once - at RUSTLIB/core/src/panic/unwind_safe.rs:LL:CC - 16: std::panicking::try::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC - 17: std::panicking::try - at RUSTLIB/std/src/panicking.rs:LL:CC - 18: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC - 19: miri::eval::eval_entry - at ./src/eval.rs:LL:CC - 20: ::after_analysis - at ./src/bin/miri.rs:LL:CC - 21: rustc_driver_impl::run_compiler::{closure#0}::{closure#2} - at /home/gh-bjorn3/rust/compiler/rustc_driver_impl/src/lib.rs:LL:CC - 22: rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure#0} - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/passes.rs:LL:CC - 23: ::create_global_ctxt::{closure#3} - at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context.rs:LL:CC - 24: rustc_middle::ty::context::tls::enter_context::{closure#0} - at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context/tls.rs:LL:CC - 25: >>::try_with - at RUSTLIB/std/src/thread/local.rs:LL:CC - 26: >>::with - at RUSTLIB/std/src/thread/local.rs:LL:CC - 27: rustc_middle::ty::context::tls::enter_context - at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context/tls.rs:LL:CC - 28: ::create_global_ctxt - at /home/gh-bjorn3/rust/compiler/rustc_middle/src/ty/context.rs:LL:CC - 29: rustc_interface::passes::create_and_enter_global_ctxt::{closure#2} - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/passes.rs:LL:CC - 30: , rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>::{closure#2} as core::ops::function::FnOnce<(&rustc_interface::interface::Compiler, &std::sync::once_lock::OnceLock, &rustc_data_structures::sync::worker_local::WorkerLocal, &rustc_data_structures::sync::worker_local::WorkerLocal, rustc_driver_impl::run_compiler::{closure#0}::{closure#2})>>::call_once::{shim:vtable#0} - at RUSTLIB/core/src/ops/function.rs:LL:CC - 31: core::ops::function::FnOnce<(&'a rustc_interface::interface::Compiler, &'a std::sync::once_lock::OnceLock>, &'a rustc_data_structures::sync::worker_local::WorkerLocal>, &'a rustc_data_structures::sync::worker_local::WorkerLocal>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}), Output = core::option::Option>> as core::ops::function::FnOnce<(&rustc_interface::interface::Compiler, &std::sync::once_lock::OnceLock, &rustc_data_structures::sync::worker_local::WorkerLocal, &rustc_data_structures::sync::worker_local::WorkerLocal, rustc_driver_impl::run_compiler::{closure#0}::{closure#2})>>::call_once - at RUSTLIB/alloc/src/boxed.rs:LL:CC - 32: rustc_interface::passes::create_and_enter_global_ctxt - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/passes.rs:LL:CC - 33: rustc_driver_impl::run_compiler::{closure#0} - at /home/gh-bjorn3/rust/compiler/rustc_driver_impl/src/lib.rs:LL:CC - 34: rustc_interface::interface::run_compiler::{closure#1}::{closure#0} - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/interface.rs:LL:CC - 35: ::{closure#1}::{closure#0}> as core::ops::function::FnOnce<()>>::call_once - at RUSTLIB/core/src/panic/unwind_safe.rs:LL:CC - 36: std::panicking::try::do_call - at RUSTLIB/std/src/panicking.rs:LL:CC - 37: std::panicking::try - at RUSTLIB/std/src/panicking.rs:LL:CC - 38: std::panic::catch_unwind - at RUSTLIB/std/src/panic.rs:LL:CC - 39: rustc_interface::interface::run_compiler::{closure#1} - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/interface.rs:LL:CC - 40: rustc_interface::util::run_in_thread_pool_with_globals::{closure#0} - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/util.rs:LL:CC - 41: rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure#0} - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/util.rs:LL:CC - 42: >::set - at CARGO_REGISTRY/.../lib.rs:LL:CC - 43: rustc_span::create_session_globals_then - at /home/gh-bjorn3/rust/compiler/rustc_span/src/lib.rs:LL:CC - 44: rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0} - at /home/gh-bjorn3/rust/compiler/rustc_interface/src/util.rs:LL:CC -note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. - -error: the compiler unexpectedly panicked. this is a bug. - -note: we would appreciate a bug report: https://github.com/rust-lang/miri/issues/new - -note: please make sure that you have updated to the latest nightly - -note: please attach the file at `/home/gh-bjorn3/rust/src/tools/miri/rustc-ice-2024-12-20T10_31_46-710436.txt` to your bug report - -note: compiler flags: -Z ui-testing - -query stack during panic: -end of query stack - -Miri caused an ICE during evaluation. Here's the interpreter backtrace at the time of the panic: -note: the place in the program where the ICE was triggered - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - | -LL | let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `std::sys::alloc::unix::aligned_malloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` +error: unsupported operation: creating allocation with alignment ALIGN exceeding rustc's maximum supported value --> tests/fail/alloc/unsupported_big_alignment.rs:LL:CC | LL | __rust_alloc(1, 1 << 30); - | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: inside `>::call_once - shim(fn())` at RUSTLIB/core/src/ops/function.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_begin_short_backtrace::` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::ops::function::impls:: for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at RUSTLIB/core/src/ops/function.rs:LL:CC - = note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::r#try:: i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::panicking::r#try::do_call::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panicking::r#try::` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::panic::catch_unwind::<{closure@std::rt::lang_start_internal::{closure#1}}, isize>` at RUSTLIB/std/src/panic.rs:LL:CC - = note: inside `std::rt::lang_start_internal` at RUSTLIB/std/src/rt.rs:LL:CC - = note: inside `std::rt::lang_start::<()>` at RUSTLIB/std/src/rt.rs:LL:CC + | ^^^^^^^^^^^^^^^^^^^^^^^^ creating allocation with alignment ALIGN exceeding rustc's maximum supported value + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support + = note: BACKTRACE: + = note: inside `main` at tests/fail/alloc/unsupported_big_alignment.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 diff --git a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr index b7cc9f1a64904..0a36d3d58b616 100644 --- a/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr +++ b/src/tools/miri/tests/fail/alloc/unsupported_non_power_two_alignment.stderr @@ -1,29 +1,13 @@ -thread 'main' panicked at RUSTLIB/core/src/panicking.rs:LL:CC: -unsafe precondition(s) violated: Layout::from_size_align_unchecked requires that align is a power of 2 and the rounded-up allocation size does not exceed isize::MAX -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -note: in Miri, you may have to set `MIRIFLAGS=-Zmiri-env-forward=RUST_BACKTRACE` for the environment variable to have an effect -thread caused non-unwinding panic. aborting. -error: abnormal termination: the program aborted execution - --> RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - | -LL | unsafe { libc::abort() } - | ^^^^^^^^^^^^^ the program aborted execution - | - = note: BACKTRACE: - = note: inside `std::sys::pal::PLATFORM::abort_internal` at RUSTLIB/std/src/sys/pal/PLATFORM/mod.rs:LL:CC - = note: inside `std::panicking::rust_panic_with_hook` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside closure at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `std::sys::backtrace::__rust_end_short_backtrace::<{closure@std::panicking::begin_panic_handler::{closure#0}}, !>` at RUSTLIB/std/src/sys/backtrace.rs:LL:CC - = note: inside `std::panicking::begin_panic_handler` at RUSTLIB/std/src/panicking.rs:LL:CC - = note: inside `core::panicking::panic_nounwind` at RUSTLIB/core/src/panicking.rs:LL:CC - = note: inside `std::alloc::Layout::from_size_align_unchecked::precondition_check` at RUSTLIB/core/src/ub_checks.rs:LL:CC - = note: inside `std::alloc::Layout::from_size_align_unchecked` at RUSTLIB/core/src/ub_checks.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` +error: Undefined Behavior: creating allocation with non-power-of-two alignment ALIGN --> tests/fail/alloc/unsupported_non_power_two_alignment.rs:LL:CC | LL | __rust_alloc(1, 3); - | ^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ creating allocation with non-power-of-two alignment ALIGN + | + = 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/alloc/unsupported_non_power_two_alignment.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr index 5e49ef214095a..ef1aa74ddf4ba 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.tree.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> RUSTLIB/alloc/src/boxed.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) @@ -25,8 +25,6 @@ LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit = note: BACKTRACE (of the first span): - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr index 4b264a73dff6b..28fcd1411f962 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.tree.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> RUSTLIB/alloc/src/boxed.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the accessed tag is foreign to the protected tag (i.e., it is not a child) @@ -25,8 +25,6 @@ LL | || drop(Box::from_raw(ptr)), | ^^^^^^^^^^^^^^^^^^ = help: this transition corresponds to a temporary loss of write permissions until function exit = note: BACKTRACE (of the first span): - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr index 48e84a8b04900..18d1fb6939540 100644 --- a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr +++ b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through (root of the allocation) at ALLOC[0x0] is forbidden - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through (root of the allocation) at ALLOC[0x0] is forbidden +LL | unsafe { dealloc(ptr, l) }; + | ^^^^^^^^^^^^^^^ deallocation through (root of the allocation) at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the allocation of the accessed tag (root of the allocation) also contains the strongly protected tag @@ -18,13 +18,7 @@ help: the strongly protected tag was created here, in the initial state Re LL | fn test(_x: &mut (), ptr: *mut u8, l: Layout) { | ^^ = note: BACKTRACE (of the first span): - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `test` - --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC - | -LL | unsafe { dealloc(ptr, l) }; - | ^^^^^^^^^^^^^^^ + = note: inside `test` at tests/fail/both_borrows/zero-sized-protected.rs:LL:CC note: inside `main` --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC | diff --git a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr index 767a08e48de0f..8eb4ebbcf729d 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_read_race1.stderr @@ -1,8 +1,13 @@ error: Undefined Behavior: Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here +LL | / __rust_dealloc( +LL | | +LL | | ptr.0 as *mut _, +LL | | std::mem::size_of::(), +LL | | std::mem::align_of::(), +LL | | ); + | |_____________^ Data race detected between (1) non-atomic read on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here | help: and (1) occurred earlier here --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC @@ -12,18 +17,7 @@ LL | let _val = *ptr.0; = 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 (of the first span) on thread `unnamed-ID`: - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside closure - --> tests/fail/data_race/dealloc_read_race1.rs:LL:CC - | -LL | / __rust_dealloc( -LL | | -LL | | ptr.0 as *mut _, -LL | | std::mem::size_of::(), -LL | | std::mem::align_of::(), -LL | | ); - | |_____________^ + = note: inside closure at tests/fail/data_race/dealloc_read_race1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr index 9b9e3e40fe5a4..48d974241aada 100644 --- a/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr +++ b/src/tools/miri/tests/fail/data_race/dealloc_write_race1.stderr @@ -1,8 +1,13 @@ error: Undefined Behavior: Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here +LL | / __rust_dealloc( +LL | | +LL | | ptr.0 as *mut _, +LL | | std::mem::size_of::(), +LL | | std::mem::align_of::(), +LL | | ); + | |_____________^ Data race detected between (1) non-atomic write on thread `unnamed-ID` and (2) deallocation on thread `unnamed-ID` at ALLOC. (2) just happened here | help: and (1) occurred earlier here --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC @@ -12,18 +17,7 @@ LL | *ptr.0 = 2; = 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 (of the first span) on thread `unnamed-ID`: - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside closure - --> tests/fail/data_race/dealloc_write_race1.rs:LL:CC - | -LL | / __rust_dealloc( -LL | | -LL | | ptr.0 as *mut _, -LL | | std::mem::size_of::(), -LL | | std::mem::align_of::(), -LL | | ); - | |_____________^ + = note: inside closure at tests/fail/data_race/dealloc_write_race1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/memleak.stderr b/src/tools/miri/tests/fail/memleak.stderr index b73b79cba1bb7..89db0f1eb1628 100644 --- a/src/tools/miri/tests/fail/memleak.stderr +++ b/src/tools/miri/tests/fail/memleak.stderr @@ -1,17 +1,11 @@ -error: memory leaked: ALLOC (C heap, size: 4, align: 4), allocated here: - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - | -LL | unsafe { libc::malloc(layout.size()) as *mut u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` +error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: --> tests/fail/memleak.rs:LL:CC | LL | std::mem::forget(Box::new(42)); | ^^^^^^^^^^^^ + | + = note: BACKTRACE: + = note: inside `main` at tests/fail/memleak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr index 5b9f73f5c61e7..6850928e1503c 100644 --- a/src/tools/miri/tests/fail/memleak_no_backtrace.stderr +++ b/src/tools/miri/tests/fail/memleak_no_backtrace.stderr @@ -1,4 +1,4 @@ -error: memory leaked: ALLOC (C heap, size: 4, align: 4) +error: memory leaked: ALLOC (Rust heap, size: 4, align: 4) note: set `MIRIFLAGS=-Zmiri-ignore-leaks` to disable this check diff --git a/src/tools/miri/tests/fail/memleak_rc.stderr b/src/tools/miri/tests/fail/memleak_rc.stderr index 07e4cf2bd5eb1..df12eeed6ac64 100644 --- a/src/tools/miri/tests/fail/memleak_rc.stderr +++ b/src/tools/miri/tests/fail/memleak_rc.stderr @@ -1,12 +1,10 @@ -error: memory leaked: ALLOC (C heap, size: 32, align: 16), allocated here: - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC +error: memory leaked: ALLOC (Rust heap, SIZE, ALIGN), allocated here: + --> RUSTLIB/alloc/src/rc.rs:LL:CC | -LL | unsafe { libc::malloc(layout.size()) as *mut u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value })) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: BACKTRACE: - = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside `std::rc::Rc::>>::new` at RUSTLIB/alloc/src/rc.rs:LL:CC note: inside `main` --> tests/fail/memleak_rc.rs:LL:CC diff --git a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr index 5dd163ca5facf..f4cfa49c1564e 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/deallocate_against_protector1.stderr @@ -1,14 +1,12 @@ error: Undefined Behavior: deallocating while item [Unique for ] is strongly protected - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> RUSTLIB/alloc/src/boxed.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [Unique for ] is strongly protected +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocating while item [Unique for ] is strongly protected | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information = note: BACKTRACE: - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr index 7459ffc9fba47..ddf8dbea31f59 100644 --- a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr +++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: attempting deallocation using at ALLOC, but that tag does not exist in the borrow stack for this location - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> tests/fail/stacked_borrows/illegal_deALLOC.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempting deallocation using at ALLOC, but that tag does not exist in the borrow stack for this location +LL | dealloc(ptr2, Layout::from_size_align_unchecked(1, 1)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempting deallocation using at ALLOC, but that tag does not exist in the borrow stack for this location | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information @@ -17,13 +17,7 @@ help: was later invalidated at offsets [0x0..0x1] by a write access LL | ptr1.write(0); | ^^^^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside `main` - --> tests/fail/stacked_borrows/illegal_deALLOC.rs:LL:CC - | -LL | dealloc(ptr2, Layout::from_size_align_unchecked(1, 1)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: inside `main` at tests/fail/stacked_borrows/illegal_deALLOC.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tls_macro_leak.stderr b/src/tools/miri/tests/fail/tls_macro_leak.stderr index caac06ff4e4e9..512932b3cb8a6 100644 --- a/src/tools/miri/tests/fail/tls_macro_leak.stderr +++ b/src/tools/miri/tests/fail/tls_macro_leak.stderr @@ -1,17 +1,11 @@ -error: memory leaked: ALLOC (C heap, size: 4, align: 4), allocated here: - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - | -LL | unsafe { libc::malloc(layout.size()) as *mut u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside closure +error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: --> tests/fail/tls_macro_leak.rs:LL:CC | LL | cell.set(Some(Box::leak(Box::new(123)))); | ^^^^^^^^^^^^^ + | + = note: BACKTRACE: + = note: inside closure at tests/fail/tls_macro_leak.rs:LL:CC = note: inside `std::thread::LocalKey::>>::try_with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC = note: inside `std::thread::LocalKey::>>::with::<{closure@tests/fail/tls_macro_leak.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/local.rs:LL:CC note: inside closure diff --git a/src/tools/miri/tests/fail/tls_static_leak.stderr b/src/tools/miri/tests/fail/tls_static_leak.stderr index 946a2927f67a8..24306cca7ffdd 100644 --- a/src/tools/miri/tests/fail/tls_static_leak.stderr +++ b/src/tools/miri/tests/fail/tls_static_leak.stderr @@ -1,17 +1,11 @@ -error: memory leaked: ALLOC (C heap, size: 4, align: 4), allocated here: - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - | -LL | unsafe { libc::malloc(layout.size()) as *mut u8 } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: BACKTRACE: - = note: inside `std::sys::alloc::unix::::alloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_alloc` at RUSTLIB/std/src/alloc.rs:LL:CC -note: inside closure +error: memory leaked: ALLOC (Rust heap, size: 4, align: 4), allocated here: --> tests/fail/tls_static_leak.rs:LL:CC | LL | TLS.set(Some(Box::leak(Box::new(123)))); | ^^^^^^^^^^^^^ + | + = note: BACKTRACE: + = note: inside closure at tests/fail/tls_static_leak.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr index f7066853827e8..f6197a2acb391 100644 --- a/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr +++ b/src/tools/miri/tests/fail/tree_borrows/strongly-protected.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: deallocation through at ALLOC[0x0] is forbidden - --> RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC + --> RUSTLIB/alloc/src/boxed.rs:LL:CC | -LL | unsafe { libc::free(ptr as *mut libc::c_void) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden +LL | self.1.deallocate(From::from(ptr.cast()), layout); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ deallocation through at ALLOC[0x0] is forbidden | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental = help: the allocation of the accessed tag also contains the strongly protected tag @@ -18,8 +18,6 @@ help: the strongly protected tag was created here, in the initial state Re LL | fn inner(x: &mut i32, f: fn(*mut i32)) { | ^ = note: BACKTRACE (of the first span): - = note: inside `std::sys::alloc::unix::::dealloc` at RUSTLIB/std/src/sys/alloc/unix.rs:LL:CC - = note: inside `std::alloc::__default_lib_allocator::__rust_dealloc` at RUSTLIB/std/src/alloc.rs:LL:CC = note: inside ` as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC = note: inside `std::ptr::drop_in_place::> - shim(Some(std::boxed::Box))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC = note: inside `std::mem::drop::>` at RUSTLIB/core/src/mem/mod.rs:LL:CC diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr index 420b4e051affd..0996e5d11eff6 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.stderr @@ -16,7 +16,7 @@ LL | drop(slice1.cmp(slice2)); | ^^^^^^^^^^^^^^^^^^ Uninitialized memory occurred at ALLOC[0x4..0x10], in this allocation: -ALLOC (C heap, size: 32, align: 16) { +ALLOC (Rust heap, size: 32, align: 8) { 0x00 │ 41 42 43 44 __ __ __ __ __ __ __ __ __ __ __ __ │ ABCD░░░░░░░░░░░░ 0x10 │ 00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ │ .░░░░░░░░░░░░░░░ } diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr index 59aae23a66c21..bcde9377c5400 100644 --- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr +++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.stderr @@ -16,7 +16,7 @@ LL | drop(slice1.cmp(slice2)); | ^^^^^^^^^^^^^^^^^^ Uninitialized memory occurred at ALLOC[0x4..0x8], in this allocation: -ALLOC (C heap, size: 16, align: 16) { +ALLOC (Rust heap, size: 16, align: 8) { ╾42[ALLOC] (1 ptr byte)╼ 12 13 ╾43[ALLOC] (1 ptr byte)╼ __ __ __ __ __ __ __ __ __ __ __ __ │ ━..━░░░░░░░░░░░░ } ALLOC (global (static or const), size: 1, align: 1) { From b3a80cbcf3dfbba86e4284bd404844467b801ba7 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 12:33:19 +0000 Subject: [PATCH 7/8] Use cfg(bootstrap) as necessary --- library/alloc/src/alloc.rs | 24 ++++++++++++++++++ library/std/src/alloc.rs | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index d3d329ba51ff8..f182409730fbe 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -421,6 +421,7 @@ pub use std::alloc::handle_alloc_error; #[doc(hidden)] #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(not(bootstrap))] pub mod __alloc_error_handler { #[rustc_std_internal_symbol] #[linkage = "weak"] @@ -444,3 +445,26 @@ pub mod __alloc_error_handler { } } } + +#[cfg(all(not(no_global_oom_handling), not(test)))] +#[doc(hidden)] +#[allow(unused_attributes)] +#[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(bootstrap)] +pub mod __alloc_error_handler { + #[rustc_std_internal_symbol] + pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { + extern "Rust" { + static __rust_alloc_error_handler_should_panic: u8; + } + + if unsafe { __rust_alloc_error_handler_should_panic != 0 } { + panic!("memory allocation of {size} bytes failed") + } else { + core::panicking::panic_nounwind_fmt( + format_args!("memory allocation of {size} bytes failed"), + /* force_no_backtrace */ false, + ) + } + } +} diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 849ef537aa4ef..2c64da8f5640e 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -381,6 +381,7 @@ pub fn rust_oom(layout: Layout) -> ! { #[doc(hidden)] #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(not(bootstrap))] pub mod __default_lib_allocator { use super::{GlobalAlloc, Layout, System}; // These are used as a fallback for implementing the `__rust_alloc`, etc symbols @@ -437,3 +438,54 @@ pub mod __default_lib_allocator { } } } + +#[cfg(not(test))] +#[doc(hidden)] +#[allow(unused_attributes)] +#[unstable(feature = "alloc_internals", issue = "none")] +#[cfg(bootstrap)] +pub mod __default_lib_allocator { + use super::{GlobalAlloc, Layout, System}; + + #[rustc_std_internal_symbol] + pub unsafe extern "C" fn __rdl_alloc(size: usize, align: usize) -> *mut u8 { + // SAFETY: see the guarantees expected by `Layout::from_size_align` and + // `GlobalAlloc::alloc`. + unsafe { + let layout = Layout::from_size_align_unchecked(size, align); + System.alloc(layout) + } + } + + #[rustc_std_internal_symbol] + pub unsafe extern "C" fn __rdl_dealloc(ptr: *mut u8, size: usize, align: usize) { + // SAFETY: see the guarantees expected by `Layout::from_size_align` and + // `GlobalAlloc::dealloc`. + unsafe { System.dealloc(ptr, Layout::from_size_align_unchecked(size, align)) } + } + + #[rustc_std_internal_symbol] + pub unsafe extern "C" fn __rdl_realloc( + ptr: *mut u8, + old_size: usize, + align: usize, + new_size: usize, + ) -> *mut u8 { + // SAFETY: see the guarantees expected by `Layout::from_size_align` and + // `GlobalAlloc::realloc`. + unsafe { + let old_layout = Layout::from_size_align_unchecked(old_size, align); + System.realloc(ptr, old_layout, new_size) + } + } + + #[rustc_std_internal_symbol] + pub unsafe extern "C" fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 { + // SAFETY: see the guarantees expected by `Layout::from_size_align` and + // `GlobalAlloc::alloc_zeroed`. + unsafe { + let layout = Layout::from_size_align_unchecked(size, align); + System.alloc_zeroed(layout) + } + } +} From 7952352980f2d5326cdb80ccbd88d4fedbf430f3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:55:06 +0000 Subject: [PATCH 8/8] Update tests --- tests/run-make/bin-emit-no-symbols/rmake.rs | 2 +- tests/ui/sanitizer/dataflow-abilist.txt | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/run-make/bin-emit-no-symbols/rmake.rs b/tests/run-make/bin-emit-no-symbols/rmake.rs index 5586e53c05084..8cd7b7800f69a 100644 --- a/tests/run-make/bin-emit-no-symbols/rmake.rs +++ b/tests/run-make/bin-emit-no-symbols/rmake.rs @@ -12,5 +12,5 @@ fn main() { let out = llvm_readobj().input("app.o").arg("--symbols").run(); out.assert_stdout_contains("rust_begin_unwind"); out.assert_stdout_contains("rust_eh_personality"); - out.assert_stdout_contains("__rg_oom"); + out.assert_stdout_contains("__rust_alloc_error_handler"); } diff --git a/tests/ui/sanitizer/dataflow-abilist.txt b/tests/ui/sanitizer/dataflow-abilist.txt index fe04838f5493e..d925101e5f9f3 100644 --- a/tests/ui/sanitizer/dataflow-abilist.txt +++ b/tests/ui/sanitizer/dataflow-abilist.txt @@ -490,11 +490,6 @@ fun:__dfso_*=uninstrumented fun:__dfso_*=discard # Rust functions. -fun:__rdl_alloc=uninstrumented -fun:__rdl_alloc_zeroed=uninstrumented -fun:__rdl_dealloc=uninstrumented -fun:__rdl_realloc=uninstrumented -fun:__rg_oom=uninstrumented fun:__rust_alloc=uninstrumented fun:__rust_alloc_error_handler=uninstrumented fun:__rust_alloc_zeroed=uninstrumented