Remove #[alloc_error_handler] from the compiler and library

This commit is contained in:
Amanieu d'Antras 2023-03-22 23:43:20 +00:00
parent c9a6e41026
commit abc0660118
49 changed files with 22 additions and 842 deletions

View File

@ -4,8 +4,6 @@ builtin_macros_requires_cfg_pattern =
builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function
builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument
.label = boolean expression required

View File

@ -1,97 +0,0 @@
use crate::errors;
use crate::util::check_builtin_macro_attribute;
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, FnHeader, FnSig, Generics, StmtKind};
use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe};
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use thin_vec::{thin_vec, ThinVec};
pub fn expand(
ecx: &mut ExtCtxt<'_>,
_span: Span,
meta_item: &ast::MetaItem,
item: Annotatable,
) -> Vec<Annotatable> {
check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler);
let orig_item = item.clone();
// Allow using `#[alloc_error_handler]` on an item statement
// FIXME - if we get deref patterns, use them to reduce duplication here
let (item, is_stmt, sig_span) =
if let Annotatable::Item(item) = &item
&& let ItemKind::Fn(fn_kind) = &item.kind
{
(item, false, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else if let Annotatable::Stmt(stmt) = &item
&& let StmtKind::Item(item) = &stmt.kind
&& let ItemKind::Fn(fn_kind) = &item.kind
{
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else {
ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocErrorMustBeFn {span: item.span() });
return vec![orig_item];
};
// Generate a bunch of new items using the AllocFnFactory
let span = ecx.with_def_site_ctxt(item.span);
// Generate item statements for the allocator methods.
let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)];
// Generate anonymous constant serving as container for the allocator methods.
let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new()));
let const_body = ecx.expr_block(ecx.block(span, stmts));
let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
let const_item = if is_stmt {
Annotatable::Stmt(P(ecx.stmt_item(span, const_item)))
} else {
Annotatable::Item(const_item)
};
// Return the original item and the new methods.
vec![orig_item, const_item]
}
// #[rustc_std_internal_symbol]
// unsafe fn __rg_oom(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 {
let usize = cx.path_ident(span, Ident::new(sym::usize, span));
let ty_usize = cx.ty_path(usize);
let size = Ident::from_str_and_span("size", span);
let align = Ident::from_str_and_span("align", span);
let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]);
let layout_new = cx.expr_path(cx.path(span, layout_new));
let layout = cx.expr_call(
span,
layout_new,
thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)],
);
let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]);
let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never));
let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)];
let decl = cx.fn_decl(params, never);
let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() };
let sig = FnSig { decl, header, span: span };
let body = Some(cx.block_expr(call));
let kind = ItemKind::Fn(Box::new(Fn {
defaultness: ast::Defaultness::Final,
sig,
generics: Generics::default(),
body,
}));
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);
cx.stmt_item(sig_span, item)
}

View File

@ -19,13 +19,6 @@ pub(crate) struct OneCfgPattern {
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_alloc_error_must_be_fn)]
pub(crate) struct AllocErrorMustBeFn {
#[primary_span]
pub(crate) span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_assert_requires_boolean)]
pub(crate) struct AssertRequiresBoolean {

View File

@ -27,7 +27,6 @@
use rustc_macros::fluent_messages;
use rustc_span::symbol::sym;
mod alloc_error_handler;
mod assert;
mod cfg;
mod cfg_accessible;
@ -102,7 +101,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
}
register_attr! {
alloc_error_handler: alloc_error_handler::expand,
bench: test::expand_bench,
cfg_accessible: cfg_accessible::Expander,
cfg_eval: cfg_eval::expand,

View File

@ -1,4 +1,4 @@
#![feature(start, core_intrinsics, alloc_error_handler)]
#![feature(start, core_intrinsics)]
#![no_std]
extern crate alloc;
@ -22,11 +22,6 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {
core::intrinsics::abort();
}
#[alloc_error_handler]
fn alloc_error_handler(_: alloc::alloc::Layout) -> ! {
core::intrinsics::abort();
}
#[start]
fn main(_argc: isize, _argv: *const *const u8) -> isize {
let world: Box<&str> = Box::new("Hello World!\0");

View File

@ -6,7 +6,6 @@
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
use rustc_session::config::OomStrategy;
use rustc_span::symbol::sym;
/// Returns whether an allocator shim was created
pub(crate) fn codegen(
@ -15,13 +14,7 @@ pub(crate) fn codegen(
unwind_context: &mut UnwindContext,
) -> bool {
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
codegen_inner(
module,
unwind_context,
kind,
tcx.alloc_error_handler_kind(()).unwrap(),
tcx.sess.opts.unstable_opts.oom,
);
codegen_inner(module, unwind_context, kind, tcx.sess.opts.unstable_opts.oom);
true
}
@ -29,7 +22,6 @@ fn codegen_inner(
module: &mut impl Module,
unwind_context: &mut UnwindContext,
kind: AllocatorKind,
alloc_error_handler_kind: AllocatorKind,
oom_strategy: OomStrategy,
) {
let usize_ty = module.target_config().pointer_type();
@ -71,19 +63,6 @@ fn codegen_inner(
);
}
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,
unwind_context,
sig,
"__rust_alloc_error_handler",
&alloc_error_handler_kind.fn_name(sym::oom),
);
let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap();
let mut data_ctx = DataContext::new();
data_ctx.set_align(1);

View File

@ -1,4 +1,4 @@
#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
#![feature(start, core_intrinsics, lang_items)]
#![no_std]
extern crate alloc;
@ -21,11 +21,6 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {
core::intrinsics::abort();
}
#[alloc_error_handler]
fn alloc_error_handler(_: alloc::alloc::Layout) -> ! {
core::intrinsics::abort();
}
#[lang = "eh_personality"]
fn eh_personality() -> ! {
loop {}

View File

@ -5,11 +5,10 @@
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::OomStrategy;
use rustc_span::symbol::sym;
use crate::GccContext;
pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) {
pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind) {
let context = &mods.context;
let usize =
match tcx.sess.target.pointer_width {
@ -87,37 +86,6 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
// as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643
}
let types = [usize, usize];
let name = "__rust_alloc_error_handler".to_string();
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, void, &args, name, false);
if tcx.sess.target.default_hidden_visibility {
#[cfg(feature="master")]
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
}
let callee = alloc_error_handler_kind.fn_name(sym::oom);
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, void, &args, callee, 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::<Vec<_>>();
let _ret = context.new_call(None, callee, &args);
//llvm::LLVMSetTailCall(ret, True);
block.end_with_void_return(None);
let name = OomStrategy::SYMBOL.to_string();
let global = context.new_global(None, GlobalKind::Exported, i8, name);
let value = tcx.sess.opts.unstable_opts.oom.should_panic();

View File

@ -162,11 +162,11 @@ fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
}
impl ExtraBackendMethods for GccCodegenBackend {
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module {
fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind) -> Self::Module {
let mut mods = GccContext {
context: Context::default(),
};
unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); }
unsafe { allocator::codegen(tcx, &mut mods, module_name, kind); }
mods
}

View File

@ -4,7 +4,6 @@
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{DebugInfo, OomStrategy};
use rustc_span::symbol::sym;
use crate::debuginfo;
use crate::llvm::{self, False, True};
@ -15,7 +14,6 @@ pub(crate) unsafe fn codegen(
module_llvm: &mut ModuleLlvm,
module_name: &str,
kind: AllocatorKind,
alloc_error_handler_kind: AllocatorKind,
) {
let llcx = &*module_llvm.llcx;
let llmod = module_llvm.llmod();
@ -100,52 +98,6 @@ pub(crate) unsafe fn codegen(
llvm::LLVMDisposeBuilder(llbuilder);
}
// rust alloc error handler
let args = [usize, usize]; // size, align
let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False);
let name = "__rust_alloc_error_handler";
let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
// -> ! DIFlagNoReturn
let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx);
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]);
if tcx.sess.target.default_hidden_visibility {
llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
}
if tcx.sess.must_emit_unwind_tables() {
let uwtable = attributes::uwtable_attr(llcx);
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
}
let callee = alloc_error_handler_kind.fn_name(sym::oom);
let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
// -> ! DIFlagNoReturn
attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);
llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
let args = args
.iter()
.enumerate()
.map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
.collect::<Vec<_>>();
let ret = llvm::LLVMRustBuildCall(
llbuilder,
ty,
callee,
args.as_ptr(),
args.len() as c_uint,
[].as_ptr(),
0 as c_uint,
);
llvm::LLVMSetTailCall(ret, True);
llvm::LLVMBuildRetVoid(llbuilder);
llvm::LLVMDisposeBuilder(llbuilder);
// __rust_alloc_error_handler_should_panic
let name = OomStrategy::SYMBOL;
let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8);

View File

@ -115,11 +115,10 @@ fn codegen_allocator<'tcx>(
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, kind);
}
module_llvm
}

View File

@ -219,7 +219,7 @@ fn exported_symbols_provider_local(
for symbol_name in ALLOCATOR_METHODS
.iter()
.map(|method| format!("__rust_{}", method.name))
.chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()])
.chain([OomStrategy::SYMBOL.to_string()])
{
let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));

View File

@ -635,16 +635,9 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
if let Some(kind) = allocator_kind_for_codegen(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(),
)
});
let module_llvm = tcx
.sess
.time("write_allocator_module", || backend.codegen_allocator(tcx, &llmod_id, kind));
ongoing_codegen.submit_pre_codegened_module_to_llvm(
tcx,

View File

@ -123,7 +123,6 @@ fn codegen_allocator<'tcx>(
tcx: TyCtxt<'tcx>,
module_name: &str,
kind: AllocatorKind,
alloc_error_handler_kind: AllocatorKind,
) -> Self::Module;
/// This generates the codegen unit and returns it along with
/// a `u64` giving an estimate of the unit's processing cost.

View File

@ -291,8 +291,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
(active, abi_x86_interrupt, "1.17.0", Some(40180), None),
/// Allows additional const parameter types, such as `&'static str` or user defined types
(incomplete, adt_const_params, "1.56.0", Some(95174), None),
/// Allows defining an `#[alloc_error_handler]`.
(active, alloc_error_handler, "1.29.0", Some(51540), None),
/// Allows trait methods with arbitrary self types.
(active, arbitrary_self_types, "1.23.0", Some(44874), None),
/// Allows using `const` operands in inline assembly.

View File

@ -47,6 +47,8 @@ macro_rules! declare_features {
(removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
Some("merged into `#![feature(slice_patterns)]`")),
/// Allows defining an `#[alloc_error_handler]`.
(removed, alloc_error_handler, "CURRENT_RUSTC_VERSION", Some(51540), None, Some("now handled by panic handler")),
(removed, allocator, "1.0.0", None, None, None),
/// Allows a test to fail without failing the whole suite.
(removed, allow_fail, "1.19.0", Some(46488), None, Some("removed due to no clear use cases")),

View File

@ -155,19 +155,9 @@ metadata_no_multiple_global_alloc =
metadata_prev_global_alloc =
previous global allocator defined here
metadata_no_multiple_alloc_error_handler =
cannot define multiple allocation error handlers
.label = cannot define a new allocation error handler
metadata_prev_alloc_error_handler =
previous allocation error handler defined here
metadata_conflicting_global_alloc =
the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name}
metadata_conflicting_alloc_error_handler =
the `#[alloc_error_handler]` in {$other_crate_name} conflicts with allocation error handler in: {$crate_name}
metadata_global_alloc_required =
no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait

View File

@ -38,13 +38,8 @@ pub struct CStore {
/// This crate needs an allocator and either provides it itself, or finds it in a dependency.
/// If the above is true, then this field denotes the kind of the found allocator.
allocator_kind: Option<AllocatorKind>,
/// This crate needs an allocation error handler and either provides it itself, or finds it in a dependency.
/// If the above is true, then this field denotes the kind of the found allocator.
alloc_error_handler_kind: Option<AllocatorKind>,
/// This crate has a `#[global_allocator]` item.
has_global_allocator: bool,
/// This crate has a `#[alloc_error_handler]` item.
has_alloc_error_handler: bool,
/// The interned [StableCrateId]s.
pub(crate) stable_crate_ids: StableCrateIdMap,
@ -221,18 +216,10 @@ pub(crate) fn allocator_kind(&self) -> Option<AllocatorKind> {
self.allocator_kind
}
pub(crate) fn alloc_error_handler_kind(&self) -> Option<AllocatorKind> {
self.alloc_error_handler_kind
}
pub(crate) fn has_global_allocator(&self) -> bool {
self.has_global_allocator
}
pub(crate) fn has_alloc_error_handler(&self) -> bool {
self.has_alloc_error_handler
}
pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) {
let json_unused_externs = tcx.sess.opts.json_unused_externs;
@ -268,9 +255,7 @@ pub fn new(sess: &Session) -> CStore {
metas: IndexVec::from_iter(iter::once(None)),
injected_panic_runtime: None,
allocator_kind: None,
alloc_error_handler_kind: None,
has_global_allocator: false,
has_alloc_error_handler: false,
stable_crate_ids,
unused_externs: Vec::new(),
}
@ -776,14 +761,6 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
}
spans => !spans.is_empty(),
};
self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(krate) {
[span1, span2, ..] => {
self.sess
.emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 });
true
}
spans => !spans.is_empty(),
};
// Check to see if we actually need an allocator. This desire comes
// about through the `#![needs_allocator]` attribute and is typically
@ -824,21 +801,6 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
}
}
}
let mut alloc_error_handler =
self.cstore.has_alloc_error_handler.then(|| Symbol::intern("this crate"));
for (_, data) in self.cstore.iter_crate_data() {
if data.has_alloc_error_handler() {
match alloc_error_handler {
Some(other_crate) => {
self.sess.emit_err(errors::ConflictingAllocErrorHandler {
crate_name: data.name(),
other_crate_name: other_crate,
});
}
None => alloc_error_handler = Some(data.name()),
}
}
}
if global_allocator.is_some() {
self.cstore.allocator_kind = Some(AllocatorKind::Global);
@ -854,14 +816,6 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
}
self.cstore.allocator_kind = Some(AllocatorKind::Default);
}
if alloc_error_handler.is_some() {
self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Global);
} else {
// The alloc crate provides a default allocation error handler if
// one isn't specified.
self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Default);
}
}
fn inject_dependency_if(
@ -1037,28 +991,6 @@ fn visit_item(&mut self, item: &'ast ast::Item) {
f.spans
}
fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec<Span> {
struct Finder {
name: Symbol,
spans: Vec<Span>,
}
impl<'ast> visit::Visitor<'ast> for Finder {
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)
{
self.spans.push(item.span);
}
visit::walk_item(self, item)
}
}
let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::oom));
let mut f = Finder { name, spans: Vec::new() };
visit::walk_crate(&mut f, krate);
f.spans
}
// On Windows the compiler would sometimes intermittently fail to open the
// proc-macro DLL with `Error::LoadLibraryExW`. It is suspected that something in the
// system still holds a lock on the file, so we retry a few times before calling it

View File

@ -352,16 +352,6 @@ pub struct NoMultipleGlobalAlloc {
pub span1: Span,
}
#[derive(Diagnostic)]
#[diag(metadata_no_multiple_alloc_error_handler)]
pub struct NoMultipleAllocErrorHandler {
#[primary_span]
#[label]
pub span2: Span,
#[label(metadata_prev_alloc_error_handler)]
pub span1: Span,
}
#[derive(Diagnostic)]
#[diag(metadata_conflicting_global_alloc)]
pub struct ConflictingGlobalAlloc {
@ -369,13 +359,6 @@ pub struct ConflictingGlobalAlloc {
pub other_crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_conflicting_alloc_error_handler)]
pub struct ConflictingAllocErrorHandler {
pub crate_name: Symbol,
pub other_crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_global_alloc_required)]
pub struct GlobalAllocRequired;

View File

@ -1692,10 +1692,6 @@ pub(crate) fn has_global_allocator(&self) -> bool {
self.root.has_global_allocator
}
pub(crate) fn has_alloc_error_handler(&self) -> bool {
self.root.has_alloc_error_handler
}
pub(crate) fn has_default_lib_allocator(&self) -> bool {
self.root.has_default_lib_allocator
}

View File

@ -290,7 +290,6 @@ fn into_args(self) -> (DefId, SimplifiedType) {
is_panic_runtime => { cdata.root.panic_runtime }
is_compiler_builtins => { cdata.root.compiler_builtins }
has_global_allocator => { cdata.root.has_global_allocator }
has_alloc_error_handler => { cdata.root.has_alloc_error_handler }
has_panic_handler => { cdata.root.has_panic_handler }
is_profiler_runtime => { cdata.root.profiler_runtime }
required_panic_strategy => { cdata.root.required_panic_strategy }
@ -379,7 +378,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
// resolve! Does this work? Unsure! That's what the issue is about
*providers = 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)
@ -496,7 +494,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)),
has_global_allocator: |tcx, LocalCrate| CStore::from_tcx(tcx).has_global_allocator(),
has_alloc_error_handler: |tcx, LocalCrate| CStore::from_tcx(tcx).has_alloc_error_handler(),
postorder_cnums: |tcx, ()| {
tcx.arena
.alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))

View File

@ -676,7 +676,6 @@ macro_rules! stat {
panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
edition: tcx.sess.edition(),
has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE),
has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
has_default_lib_allocator: attr::contains_name(&attrs, sym::default_lib_allocator),
proc_macro_data,

View File

@ -225,7 +225,6 @@ pub(crate) struct CrateRoot {
panic_in_drop_strategy: PanicStrategy,
edition: Edition,
has_global_allocator: bool,
has_alloc_error_handler: bool,
has_panic_handler: bool,
has_default_lib_allocator: bool,

View File

@ -1460,13 +1460,6 @@
desc { "checking if the crate has_global_allocator" }
separate_provide_extern
}
query has_alloc_error_handler(_: CrateNum) -> bool {
// This query depends on untracked global state in CStore
eval_always
fatal_cycle
desc { "checking if the crate has_alloc_error_handler" }
separate_provide_extern
}
query has_panic_handler(_: CrateNum) -> bool {
fatal_cycle
desc { "checking if the crate has_panic_handler" }
@ -1839,10 +1832,6 @@
eval_always
desc { "getting the allocator kind for the current crate" }
}
query alloc_error_handler_kind(_: ()) -> Option<AllocatorKind> {
eval_always
desc { "alloc error handler kind for the current crate" }
}
query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>> {
desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) }

View File

@ -397,7 +397,7 @@ fn rust_oom(layout: Layout) -> ! {
#[lang = "panic_impl"]
fn panic_impl(pi: &core::panic::PanicInfo<'_>) -> !;
// This symbol is emitted by rustc next to __rust_alloc_error_handler.
// This symbol is emitted by rustc .
// Its value depends on the -Zoom={panic,abort} compiler option.
static __rust_alloc_error_handler_should_panic: u8;
}
@ -426,13 +426,6 @@ fn rust_oom(layout: Layout) -> ! {
/// Callers of memory allocation APIs wishing to abort computation
/// in response to an allocation error are encouraged to call this function,
/// rather than directly invoking `panic!` or similar.
///
/// The default behavior of this function is to print a message to standard error
/// and abort the process.
/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`].
///
/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html
/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html
#[stable(feature = "global_alloc", since = "1.28.0")]
#[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")]
#[cfg(all(not(no_global_oom_handling), not(test)))]
@ -453,6 +446,7 @@ fn rt_error(layout: Layout) -> ! {
#[cfg(all(not(no_global_oom_handling), test))]
pub use std::alloc::handle_alloc_error;
#[cfg(bootstrap)]
#[cfg(all(not(no_global_oom_handling), not(test)))]
#[doc(hidden)]
#[allow(unused_attributes)]

View File

@ -1531,16 +1531,6 @@ macro_rules! trace_macros {
/* compiler built-in */
}
/// Attribute macro applied to a function to register it as a handler for allocation failure.
///
/// See also [`std::alloc::handle_alloc_error`](../../../std/alloc/fn.handle_alloc_error.html).
#[unstable(feature = "alloc_error_handler", issue = "51540")]
#[allow_internal_unstable(rustc_attrs)]
#[rustc_builtin_macro]
pub macro alloc_error_handler($item:item) {
/* compiler built-in */
}
/// Keeps the item it's applied to if the passed path is accessible, and removes it otherwise.
#[unstable(
feature = "cfg_accessible",

View File

@ -76,9 +76,7 @@
// Do not `doc(no_inline)` so that they become doc items on their own
// (no public module for them to be re-exported from).
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
pub use crate::macros::builtin::{
alloc_error_handler, bench, derive, global_allocator, test, test_case,
};
pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case};
#[unstable(feature = "derive_const", issue = "none")]
pub use crate::macros::builtin::derive_const;

View File

@ -57,9 +57,8 @@
#![stable(feature = "alloc_module", since = "1.28.0")]
use core::intrinsics;
use core::ptr;
use core::ptr::NonNull;
use core::sync::atomic::{AtomicPtr, Ordering};
use core::{mem, ptr};
#[stable(feature = "alloc_module", since = "1.28.0")]
#[doc(inline)]
@ -286,76 +285,6 @@ unsafe fn shrink(
}
}
static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
/// Registers a custom allocation error hook, replacing any that was previously registered.
///
/// The allocation error hook is invoked when an infallible memory allocation fails, before
/// the runtime aborts. The default hook prints a message to standard error,
/// but this behavior can be customized with the [`set_alloc_error_hook`] and
/// [`take_alloc_error_hook`] functions.
///
/// The hook is provided with a `Layout` struct which contains information
/// about the allocation that failed.
///
/// The allocation error hook is a global resource.
///
/// # Examples
///
/// ```
/// #![feature(alloc_error_hook)]
///
/// use std::alloc::{Layout, set_alloc_error_hook};
///
/// fn custom_alloc_error_hook(layout: Layout) {
/// panic!("memory allocation of {} bytes failed", layout.size());
/// }
///
/// set_alloc_error_hook(custom_alloc_error_hook);
/// ```
#[unstable(feature = "alloc_error_hook", issue = "51245")]
pub fn set_alloc_error_hook(hook: fn(Layout)) {
HOOK.store(hook as *mut (), Ordering::SeqCst);
}
/// Unregisters the current allocation error hook, returning it.
///
/// *See also the function [`set_alloc_error_hook`].*
///
/// If no custom hook is registered, the default hook will be returned.
#[unstable(feature = "alloc_error_hook", issue = "51245")]
pub fn take_alloc_error_hook() -> fn(Layout) {
let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } }
}
fn default_alloc_error_hook(layout: Layout) {
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;
}
#[allow(unused_unsafe)]
if unsafe { __rust_alloc_error_handler_should_panic != 0 } {
panic!("memory allocation of {} bytes failed", layout.size());
} else {
rtprintpanic!("memory allocation of {} bytes failed\n", layout.size());
}
}
#[cfg(not(test))]
#[doc(hidden)]
#[alloc_error_handler]
#[unstable(feature = "alloc_internals", issue = "none")]
pub fn rust_oom(layout: Layout) -> ! {
let hook = HOOK.load(Ordering::SeqCst);
let hook: fn(Layout) =
if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } };
hook(layout);
crate::process::abort()
}
#[cfg(not(test))]
#[doc(hidden)]
#[allow(unused_attributes)]

View File

@ -236,7 +236,6 @@
//
// Language features:
// tidy-alphabetical-start
#![feature(alloc_error_handler)]
#![feature(allocator_internals)]
#![feature(allow_internal_unsafe)]
#![feature(allow_internal_unstable)]

View File

@ -60,9 +60,7 @@
// Do not `doc(no_inline)` so that they become doc items on their own
// (no public module for them to be re-exported from).
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
pub use core::prelude::v1::{
alloc_error_handler, bench, derive, global_allocator, test, test_case,
};
pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case};
#[unstable(feature = "derive_const", issue = "none")]
pub use core::prelude::v1::derive_const;

View File

@ -381,10 +381,6 @@ macro_rules! experimental {
rustc_attr!(rustc_allocator, Normal, template!(Word), WarnFollowing, IMPL_DETAIL),
rustc_attr!(rustc_nounwind, Normal, template!(Word), WarnFollowing, IMPL_DETAIL),
gated!(
alloc_error_handler, Normal, template!(Word), WarnFollowing,
experimental!(alloc_error_handler)
),
gated!(
default_lib_allocator, Normal, template!(Word), WarnFollowing, allocator_internals,
experimental!(default_lib_allocator),

View File

@ -6,4 +6,3 @@ all:
$(RUSTC) --emit=obj app.rs
nm $(TMPDIR)/app.o | $(CGREP) rust_begin_unwind
nm $(TMPDIR)/app.o | $(CGREP) rust_eh_personality
nm $(TMPDIR)/app.o | $(CGREP) __rg_oom

View File

@ -1,5 +1,5 @@
#![crate_type = "bin"]
#![feature(lang_items, alloc_error_handler)]
#![feature(lang_items)]
#![no_main]
#![no_std]
@ -13,8 +13,3 @@ fn panic(_: &PanicInfo) -> ! {
#[lang = "eh_personality"]
fn eh() {}
#[alloc_error_handler]
fn oom(_: Layout) -> ! {
loop {}
}

View File

@ -1,19 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# Test that previously triggered a linker failure with root cause
# similar to one found in the issue #69368.
#
# The crate that provides oom lang item is missing some other lang
# items. Necessary to prevent the use of start-group / end-group.
#
# The weak lang items are defined in a separate compilation units,
# so that linker could omit them if not used.
#
# The crates that need those weak lang items are dependencies of
# crates that provide them.
all:
$(RUSTC) a.rs
$(RUSTC) b.rs
$(RUSTC) c.rs

View File

@ -1,26 +0,0 @@
#![crate_type = "rlib"]
#![feature(lang_items)]
#![feature(panic_unwind)]
#![no_std]
extern crate panic_unwind;
#[panic_handler]
pub fn panic_handler(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[no_mangle]
extern "C" fn __rust_drop_panic() -> ! {
loop {}
}
#[no_mangle]
extern "C" fn __rust_foreign_exception() -> ! {
loop {}
}
#[lang = "eh_personality"]
fn eh_personality() {
loop {}
}

View File

@ -1,8 +0,0 @@
#![crate_type = "rlib"]
#![feature(alloc_error_handler)]
#![no_std]
#[alloc_error_handler]
pub fn error_handler(_: core::alloc::Layout) -> ! {
panic!();
}

View File

@ -1,34 +0,0 @@
#![crate_type = "bin"]
#![feature(start)]
#![no_std]
extern crate alloc;
extern crate a;
extern crate b;
use alloc::vec::Vec;
use core::alloc::*;
struct Allocator;
unsafe impl GlobalAlloc for Allocator {
unsafe fn alloc(&self, _: Layout) -> *mut u8 {
loop {}
}
unsafe fn dealloc(&self, _: *mut u8, _: Layout) {
loop {}
}
}
#[global_allocator]
static ALLOCATOR: Allocator = Allocator;
#[start]
fn main(argc: isize, _argv: *const *const u8) -> isize {
let mut v = Vec::new();
for i in 0..argc {
v.push(i);
}
v.iter().sum()
}

View File

@ -1,4 +1,4 @@
#![feature(panic_handler, alloc_error_handler)]
#![feature(panic_handler)]
#![crate_type = "cdylib"]
#![no_std]
@ -24,11 +24,6 @@ unsafe fn dealloc(&self, ptr: *mut u8, x: Layout) {
a * 2
}
#[alloc_error_handler]
fn a(_: core::alloc::Layout) -> ! {
loop {}
}
#[panic_handler]
fn b(_: &core::panic::PanicInfo) -> ! {
loop {}

View File

@ -1,18 +0,0 @@
// compile-flags:-C panic=abort
#![feature(alloc_error_handler)]
#![no_std]
#![no_main]
use core::alloc::Layout;
#[alloc_error_handler]
fn oom(
info: &Layout, //~^ ERROR mismatched types
) -> () //~^^ ERROR mismatched types
{
loop {}
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }

View File

@ -1,44 +0,0 @@
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-1.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | // fn oom(
LL | || info: &Layout,
LL | || ) -> ()
| ||_______- arguments to this function are incorrect
LL | | {
LL | | loop {}
LL | | }
| |__^ expected `&Layout`, found `Layout`
|
note: function defined here
--> $DIR/alloc-error-handler-bad-signature-1.rs:10:4
|
LL | fn oom(
| ^^^
LL | info: &Layout,
| -------------
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-1.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | // fn oom(
LL | || info: &Layout,
LL | || ) -> ()
| ||_______^ expected `!`, found `()`
LL | | {
LL | | loop {}
LL | | }
| |__- expected `!` because of return type
|
= note: expected type `!`
found unit type `()`
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,17 +0,0 @@
// compile-flags:-C panic=abort
#![feature(alloc_error_handler)]
#![no_std]
#![no_main]
struct Layout;
#[alloc_error_handler]
fn oom(
info: Layout, //~^ ERROR mismatched types
) { //~^^ ERROR mismatched types
loop {}
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }

View File

@ -1,50 +0,0 @@
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-2.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | // fn oom(
LL | || info: Layout,
LL | || ) {
| ||_- arguments to this function are incorrect
LL | | loop {}
LL | | }
| |__^ expected `Layout`, found `core::alloc::Layout`
|
= note: `core::alloc::Layout` and `Layout` have similar names, but are actually distinct types
note: `core::alloc::Layout` is defined in crate `core`
--> $SRC_DIR/core/src/alloc/layout.rs:LL:COL
note: `Layout` is defined in the current crate
--> $DIR/alloc-error-handler-bad-signature-2.rs:7:1
|
LL | struct Layout;
| ^^^^^^^^^^^^^
note: function defined here
--> $DIR/alloc-error-handler-bad-signature-2.rs:10:4
|
LL | fn oom(
| ^^^
LL | info: Layout,
| ------------
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> $DIR/alloc-error-handler-bad-signature-2.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | // fn oom(
LL | || info: Layout,
LL | || ) {
| ||_^ expected `!`, found `()`
LL | | loop {}
LL | | }
| |__- expected `!` because of return type
|
= note: expected type `!`
found unit type `()`
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,15 +0,0 @@
// compile-flags:-C panic=abort
#![feature(alloc_error_handler)]
#![no_std]
#![no_main]
struct Layout;
#[alloc_error_handler]
fn oom() -> ! { //~ ERROR function takes 0 arguments but 1 argument was supplied
loop {}
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! { loop {} }

View File

@ -1,21 +0,0 @@
error[E0061]: this function takes 0 arguments but 1 argument was supplied
--> $DIR/alloc-error-handler-bad-signature-3.rs:10:1
|
LL | #[alloc_error_handler]
| ---------------------- in this procedural macro expansion
LL | fn oom() -> ! {
| _-^^^^^^^^^^^^
LL | | loop {}
LL | | }
| |_- unexpected argument of type `core::alloc::Layout`
|
note: function defined here
--> $DIR/alloc-error-handler-bad-signature-3.rs:10:4
|
LL | fn oom() -> ! {
| ^^^
= note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0061`.

View File

@ -2,7 +2,7 @@
// ignore-emscripten no processes
// ignore-sgx no processes
use std::alloc::{Layout, handle_alloc_error};
use std::alloc::{handle_alloc_error, Layout};
use std::env;
use std::process::Command;
use std::str;
@ -24,5 +24,5 @@ fn main() {
.strip_suffix("qemu: uncaught target signal 6 (Aborted) - core dumped\n")
.unwrap_or(stderr);
assert_eq!(stderr, "memory allocation of 42 bytes failed\n");
assert!(stderr.contains("memory allocation of 42 bytes failed"));
}

View File

@ -1,84 +0,0 @@
// run-pass
// ignore-android no libc
// ignore-emscripten no libc
// ignore-sgx no libc
// ignore-wasm32 no libc
// only-linux
// compile-flags:-C panic=abort
// aux-build:helper.rs
#![feature(rustc_private, lang_items)]
#![feature(alloc_error_handler)]
#![no_std]
#![no_main]
extern crate alloc;
extern crate libc;
// ARM targets need these symbols
#[no_mangle]
pub fn __aeabi_unwind_cpp_pr0() {}
#[no_mangle]
pub fn __aeabi_unwind_cpp_pr1() {}
use alloc::boxed::Box;
use alloc::string::ToString;
use core::alloc::{GlobalAlloc, Layout};
use core::ptr::null_mut;
extern crate helper;
struct MyAllocator;
#[alloc_error_handler]
fn my_oom(layout: Layout) -> ! {
use alloc::fmt::write;
unsafe {
let size = layout.size();
let mut s = alloc::string::String::new();
write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap();
libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len());
libc::exit(0)
}
}
unsafe impl GlobalAlloc for MyAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
if layout.size() < 4096 { libc::malloc(layout.size()) as _ } else { null_mut() }
}
unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
}
#[global_allocator]
static A: MyAllocator = MyAllocator;
#[panic_handler]
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
unsafe {
let s = panic_info.to_string();
const PSTR: &str = "panic occurred: ";
const CR: &str = "\n";
libc::write(libc::STDERR_FILENO, PSTR.as_ptr() as *const _, PSTR.len());
libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len());
libc::write(libc::STDERR_FILENO, CR.as_ptr() as *const _, CR.len());
libc::exit(1)
}
}
// Because we are compiling this code with `-C panic=abort`, this wouldn't normally be needed.
// However, `core` and `alloc` are both compiled with `-C panic=unwind`, which means that functions
// in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't
// unwind. So, for this test case we will define the symbol.
#[lang = "eh_personality"]
extern "C" fn rust_eh_personality() {}
#[derive(Default, Debug)]
struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]);
#[no_mangle]
fn main(_argc: i32, _argv: *const *const u8) -> isize {
let zero = Box::<Page>::new(Default::default());
helper::work_with(&zero);
1
}

View File

@ -1,16 +0,0 @@
// compile-flags:-C panic=abort
#![no_std]
#![no_main]
use core::alloc::Layout;
#[alloc_error_handler] //~ ERROR use of unstable library feature 'alloc_error_handler'
fn oom(info: Layout) -> ! {
loop {}
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}

View File

@ -1,12 +0,0 @@
error[E0658]: use of unstable library feature 'alloc_error_handler'
--> $DIR/feature-gate-alloc-error-handler.rs:8:3
|
LL | #[alloc_error_handler]
| ^^^^^^^^^^^^^^^^^^^
|
= note: see issue #51540 <https://github.com/rust-lang/rust/issues/51540> for more information
= help: add `#![feature(alloc_error_handler)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -3,16 +3,10 @@
#![no_std]
#![crate_type = "staticlib"]
#![feature(alloc_error_handler)]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[alloc_error_handler]
fn oom(_: core::alloc::Layout) -> ! {
loop {}
}
extern crate alloc;