Skip to content

Make __rust_alloc_error_handler_should_panic a function #143387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions compiler/rustc_codegen_cranelift/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,19 +84,34 @@ fn codegen_inner(
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
);

let data_id = module
.declare_data(
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
Linkage::Export,
false,
false,
)
.unwrap();
let mut data = DataDescription::new();
data.set_align(1);
let val = oom_strategy.should_panic();
data.define(Box::new([val]));
module.define_data(data_id, &data).unwrap();
{
let sig = Signature {
call_conv: module.target_config().default_call_conv,
params: vec![],
returns: vec![AbiParam::new(types::I8)],
};
let func_id = module
.declare_function(
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
Linkage::Export,
&sig,
)
.unwrap();
let mut ctx = Context::new();
ctx.func.signature = sig;
{
let mut func_ctx = FunctionBuilderContext::new();
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

let block = bcx.create_block();
bcx.switch_to_block(block);
let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64);
bcx.ins().return_(&[value]);
bcx.seal_all_blocks();
bcx.finalize();
}
module.define_function(func_id, &mut ctx).unwrap();
}

{
let sig = Signature {
Expand Down
44 changes: 33 additions & 11 deletions compiler/rustc_codegen_gcc/src/allocator.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
#[cfg(feature = "master")]
use gccjit::{FnAttribute, VarAttribute};
use gccjit::FnAttribute;
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
use rustc_ast::expand::allocator::{
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
alloc_error_handler_name, default_fn_name, global_fn_name,
Expand Down Expand Up @@ -71,15 +71,13 @@ pub(crate) unsafe fn codegen(
None,
);

let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
let global = context.new_global(None, GlobalKind::Exported, i8, name);
#[cfg(feature = "master")]
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(
tcx.sess.default_visibility(),
)));
let value = tcx.sess.opts.unstable_opts.oom.should_panic();
let value = context.new_rvalue_from_int(i8, value as i32);
global.global_set_initializer_rvalue(value);
create_const_value_function(
tcx,
context,
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
i8,
context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32),
);

create_wrapper_function(
tcx,
Expand All @@ -91,6 +89,30 @@ pub(crate) unsafe fn codegen(
);
}

fn create_const_value_function(
tcx: TyCtxt<'_>,
context: &Context<'_>,
name: &str,
output: Type<'_>,
value: RValue<'_>,
) {
let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);

#[cfg(feature = "master")]
func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
tcx.sess.default_visibility(),
)));

func.add_attribute(FnAttribute::AlwaysInline);

if tcx.sess.must_emit_unwind_tables() {
// TODO(antoyo): emit unwind tables.
}

let block = func.new_block("entry");
block.end_with_return(None, value);
}

fn create_wrapper_function(
tcx: TyCtxt<'_>,
context: &Context<'_>,
Expand Down
45 changes: 37 additions & 8 deletions compiler/rustc_codegen_llvm/src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;

use crate::builder::SBuilder;
use crate::declare::declare_simple_fn;
use crate::llvm::{self, False, True, Type};
use crate::llvm::{self, False, True, Type, Value};
use crate::{SimpleCx, attributes, debuginfo};

pub(crate) unsafe fn codegen(
Expand Down Expand Up @@ -73,13 +73,14 @@ pub(crate) unsafe fn codegen(
);

unsafe {
// __rust_alloc_error_handler_should_panic
let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL);
let ll_g = cx.declare_global(&name, i8);
llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility()));
let val = tcx.sess.opts.unstable_opts.oom.should_panic();
let llval = llvm::LLVMConstInt(i8, val as u64, False);
llvm::set_initializer(ll_g, llval);
// __rust_alloc_error_handler_should_panic_v2
create_const_value_function(
tcx,
&cx,
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
&i8,
&llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, False),
);

// __rust_no_alloc_shim_is_unstable_v2
create_wrapper_function(
Expand All @@ -100,6 +101,34 @@ pub(crate) unsafe fn codegen(
}
}

fn create_const_value_function(
tcx: TyCtxt<'_>,
cx: &SimpleCx<'_>,
name: &str,
output: &Type,
value: &Value,
) {
let ty = cx.type_func(&[], output);
let llfn = declare_simple_fn(
&cx,
name,
llvm::CallConv::CCallConv,
llvm::UnnamedAddr::Global,
llvm::Visibility::from_generic(tcx.sess.default_visibility()),
ty,
);

attributes::apply_to_llfn(
llfn,
llvm::AttributePlace::Function,
&[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)],
);

let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) };
let mut bx = SBuilder::build(&cx, llbb);
bx.ret(value);
}

fn create_wrapper_function(
tcx: TyCtxt<'_>,
cx: &SimpleCx<'_>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3340,7 +3340,7 @@ pub enum OomStrategy {
}

impl OomStrategy {
pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic";
pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic_v2";

pub fn should_panic(self) -> u8 {
match self {
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,10 +429,10 @@ pub mod __alloc_error_handler {
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
// Its value depends on the -Zoom={panic,abort} compiler option.
#[rustc_std_internal_symbol]
static __rust_alloc_error_handler_should_panic: u8;
fn __rust_alloc_error_handler_should_panic_v2() -> u8;
}

if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } {
panic!("memory allocation of {size} bytes failed")
} else {
core::panicking::panic_nounwind_fmt(
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,10 @@ fn default_alloc_error_hook(layout: Layout) {
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
// Its value depends on the -Zoom={panic,abort} compiler option.
#[rustc_std_internal_symbol]
static __rust_alloc_error_handler_should_panic: u8;
fn __rust_alloc_error_handler_should_panic_v2() -> u8;
}

if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } {
panic!("memory allocation of {} bytes failed", layout.size());
} else {
// This is the default path taken on OOM, and the only path taken on stable with std.
Expand Down
11 changes: 0 additions & 11 deletions src/tools/miri/src/shims/extern_static.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Provides the `extern static` that this platform expects.

use rustc_symbol_mangling::mangle_internal_symbol;

use crate::*;

impl<'tcx> MiriMachine<'tcx> {
Expand Down Expand Up @@ -45,15 +43,6 @@ impl<'tcx> MiriMachine<'tcx> {

/// Sets up the "extern statics" for this machine.
pub fn init_extern_statics(ecx: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> {
// "__rust_alloc_error_handler_should_panic"
let val = ecx.tcx.sess.opts.unstable_opts.oom.should_panic();
let val = ImmTy::from_int(val, ecx.machine.layouts.u8);
Self::alloc_extern_static(
ecx,
&mangle_internal_symbol(*ecx.tcx, "__rust_alloc_error_handler_should_panic"),
val,
)?;

if ecx.target_os_is_unix() {
// "environ" is mandated by POSIX.
let environ = ecx.machine.env_vars.unix().environ();
Expand Down
6 changes: 6 additions & 0 deletions src/tools/miri/src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
// This is a no-op shim that only exists to prevent making the allocator shims instantly stable.
let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
}
name if name == this.mangle_internal_symbol("__rust_alloc_error_handler_should_panic_v2") => {
// Gets the value of the `oom` option.
let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
let val = this.tcx.sess.opts.unstable_opts.oom.should_panic();
this.write_int(val, dest)?;
}

// C memory handling functions
"memcmp" => {
Expand Down
4 changes: 2 additions & 2 deletions src/tools/miri/tests/pass/alloc-access-tracking.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![no_std]
#![no_main]
//@compile-flags: -Zmiri-track-alloc-id=19 -Zmiri-track-alloc-accesses -Cpanic=abort
//@normalize-stderr-test: "id 19" -> "id $$ALLOC"
//@compile-flags: -Zmiri-track-alloc-id=18 -Zmiri-track-alloc-accesses -Cpanic=abort
//@normalize-stderr-test: "id 18" -> "id $$ALLOC"
//@only-target: linux # alloc IDs differ between OSes (due to extern static allocations)

extern "Rust" {
Expand Down
Loading