Add attributes for #[global_allocator] functions
Emit `#[rustc_allocator]` etc. attributes on the functions generated by the `#[global_allocator]` macro, which will emit LLVM attributes like `"alloc-family"`. If the module with the global allocator participates in LTO, this ensures that the attributes typically emitted on the allocator declarations are not lost if the definition is imported.
This commit is contained in:
parent
32e3d9f59b
commit
bc7986ec79
2 changed files with 54 additions and 3 deletions
|
|
@ -85,7 +85,7 @@ impl AllocFnFactory<'_, '_> {
|
|||
body,
|
||||
define_opaque: None,
|
||||
}));
|
||||
let item = self.cx.item(self.span, self.attrs(), kind);
|
||||
let item = self.cx.item(self.span, self.attrs(method), kind);
|
||||
self.cx.stmt_item(self.ty_span, item)
|
||||
}
|
||||
|
||||
|
|
@ -100,8 +100,18 @@ impl AllocFnFactory<'_, '_> {
|
|||
self.cx.expr_call(self.ty_span, method, args)
|
||||
}
|
||||
|
||||
fn attrs(&self) -> AttrVec {
|
||||
thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)]
|
||||
fn attrs(&self, method: &AllocatorMethod) -> AttrVec {
|
||||
let alloc_attr = match method.name {
|
||||
sym::alloc => sym::rustc_allocator,
|
||||
sym::dealloc => sym::rustc_deallocator,
|
||||
sym::realloc => sym::rustc_reallocator,
|
||||
sym::alloc_zeroed => sym::rustc_allocator_zeroed,
|
||||
_ => unreachable!("Unknown allocator method!"),
|
||||
};
|
||||
thin_vec![
|
||||
self.cx.attr_word(sym::rustc_std_internal_symbol, self.span),
|
||||
self.cx.attr_word(alloc_attr, self.span)
|
||||
]
|
||||
}
|
||||
|
||||
fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec<Param>) -> Box<Expr> {
|
||||
|
|
|
|||
41
tests/codegen-llvm/global-allocator-attributes.rs
Normal file
41
tests/codegen-llvm/global-allocator-attributes.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
//@ compile-flags: -C opt-level=3
|
||||
#![crate_type = "lib"]
|
||||
|
||||
mod foobar {
|
||||
use std::alloc::{GlobalAlloc, Layout};
|
||||
|
||||
struct Allocator;
|
||||
|
||||
unsafe impl GlobalAlloc for Allocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
// CHECK-LABEL: ; __rustc::__rust_alloc
|
||||
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,uninitialized,aligned") allocsize(0){{.*}}
|
||||
// CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc(i[[SIZE:[0-9]+]] {{.*}}%size, i[[SIZE]] allocalign{{.*}} %align)
|
||||
panic!()
|
||||
}
|
||||
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
// CHECK-LABEL: ; __rustc::__rust_dealloc
|
||||
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("free"){{.*}}
|
||||
// CHECK-NEXT: define{{.*}} void @{{.*}}__rust_dealloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] {{.*}} %align)
|
||||
panic!()
|
||||
}
|
||||
|
||||
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
|
||||
// CHECK-LABEL: ; __rustc::__rust_realloc
|
||||
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("realloc,aligned") allocsize(3){{.*}}
|
||||
// CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_realloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align, i[[SIZE]] {{.*}} %new_size)
|
||||
panic!()
|
||||
}
|
||||
|
||||
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
|
||||
// CHECK-LABEL: ; __rustc::__rust_alloc_zeroed
|
||||
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,zeroed,aligned") allocsize(0){{.*}}
|
||||
// CHECK-NEXT: define{{.*}} noalias{{.*}} ptr @{{.*}}__rust_alloc_zeroed(i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align)
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
#[global_allocator]
|
||||
static GLOBAL: Allocator = Allocator;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue