Skip to content

Commit 1932ce3

Browse files
committed
Auto merge of #146766 - nikic:global-alloc-attr, r=nnethercote
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. There is a similar issue when the allocator shim is used, but I've opted not to fix that case in this PR, because doing that cleanly is somewhat gnarly. Related to #145995.
2 parents f6092f2 + b6456cd commit 1932ce3

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

compiler/rustc_builtin_macros/src/global_allocator.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl AllocFnFactory<'_, '_> {
8585
body,
8686
define_opaque: None,
8787
}));
88-
let item = self.cx.item(self.span, self.attrs(), kind);
88+
let item = self.cx.item(self.span, self.attrs(method), kind);
8989
self.cx.stmt_item(self.ty_span, item)
9090
}
9191

@@ -100,8 +100,18 @@ impl AllocFnFactory<'_, '_> {
100100
self.cx.expr_call(self.ty_span, method, args)
101101
}
102102

103-
fn attrs(&self) -> AttrVec {
104-
thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)]
103+
fn attrs(&self, method: &AllocatorMethod) -> AttrVec {
104+
let alloc_attr = match method.name {
105+
sym::alloc => sym::rustc_allocator,
106+
sym::dealloc => sym::rustc_deallocator,
107+
sym::realloc => sym::rustc_reallocator,
108+
sym::alloc_zeroed => sym::rustc_allocator_zeroed,
109+
_ => unreachable!("Unknown allocator method!"),
110+
};
111+
thin_vec![
112+
self.cx.attr_word(sym::rustc_std_internal_symbol, self.span),
113+
self.cx.attr_word(alloc_attr, self.span)
114+
]
105115
}
106116

107117
fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec<Param>) -> Box<Expr> {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//@ compile-flags: -C opt-level=3
2+
#![crate_type = "lib"]
3+
4+
mod foobar {
5+
use std::alloc::{GlobalAlloc, Layout};
6+
7+
struct Allocator;
8+
9+
unsafe impl GlobalAlloc for Allocator {
10+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
11+
// CHECK-LABEL: ; __rustc::__rust_alloc
12+
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,uninitialized,aligned") allocsize(0){{.*}}
13+
// CHECK-NEXT: define noalias{{.*}} ptr @{{.*}}__rust_alloc(i[[SIZE:[0-9]+]] {{.*}}%size, i[[SIZE]] allocalign{{.*}} %align)
14+
panic!()
15+
}
16+
17+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
18+
// CHECK-LABEL: ; __rustc::__rust_dealloc
19+
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("free"){{.*}}
20+
// CHECK-NEXT: define void @{{.*}}__rust_dealloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] {{.*}} %align)
21+
panic!()
22+
}
23+
24+
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
25+
// CHECK-LABEL: ; __rustc::__rust_realloc
26+
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("realloc,aligned") allocsize(3){{.*}}
27+
// CHECK-NEXT: define noalias{{.*}} ptr @{{.*}}__rust_realloc(ptr allocptr{{.*}} %ptr, i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align, i[[SIZE]] {{.*}} %new_size)
28+
panic!()
29+
}
30+
31+
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
32+
// CHECK-LABEL: ; __rustc::__rust_alloc_zeroed
33+
// CHECK-NEXT: ; Function Attrs: {{.*}}allockind("alloc,zeroed,aligned") allocsize(0){{.*}}
34+
// CHECK-NEXT: define noalias{{.*}} ptr @{{.*}}__rust_alloc_zeroed(i[[SIZE]] {{.*}} %size, i[[SIZE]] allocalign{{.*}} %align)
35+
panic!()
36+
}
37+
}
38+
39+
#[global_allocator]
40+
static GLOBAL: Allocator = Allocator;
41+
}

0 commit comments

Comments
 (0)