Skip to content

Commit 0942803

Browse files
committed
Add an "allocator" attribute to mark functions as allocators
When this attribute is applied to a function, its return value gets the noalias attribute, which is how you tell LLVM that the function returns a "new" pointer that doesn't alias anything accessible to the caller, i.e. it acts like a memory allocator. Plain malloc doesn't need this attribute because LLVM already knows about malloc and adds the attribute itself.
1 parent 49f7550 commit 0942803

File tree

5 files changed

+18
-6
lines changed

5 files changed

+18
-6
lines changed

src/liballoc/heap.rs

+1
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ mod imp {
198198
extern {}
199199

200200
extern {
201+
#[allocator]
201202
fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
202203
fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
203204
fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;

src/liballoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969

7070
#![feature(no_std)]
7171
#![no_std]
72+
#![feature(allocator)]
7273
#![feature(lang_items, unsafe_destructor)]
7374
#![feature(box_syntax)]
7475
#![feature(optin_builtin_traits)]

src/librustc_trans/trans/base.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use super::ModuleTranslation;
3333
use back::link::{mangle_exported_name};
3434
use back::{link, abi};
3535
use lint;
36-
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
36+
use llvm::{AttrHelper, BasicBlockRef, Linkage, ValueRef, Vector, get_param};
3737
use llvm;
3838
use metadata::{csearch, encoder, loader};
3939
use middle::astencode;
@@ -456,6 +456,9 @@ pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: Val
456456
llvm::FunctionIndex as c_uint,
457457
llvm::ColdAttribute as uint64_t)
458458
},
459+
"allocator" => {
460+
llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
461+
}
459462
_ => used = false,
460463
}
461464
if used {
@@ -903,8 +906,10 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
903906
ccx.sess().bug("unexpected intrinsic in trans_external_path")
904907
}
905908
_ => {
906-
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
907-
&name[..])
909+
let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name[..]);
910+
let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
911+
set_llvm_fn_attrs(ccx, &attrs, llfn);
912+
llfn
908913
}
909914
}
910915
}
@@ -2848,7 +2853,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
28482853
let abi = ccx.tcx().map.get_foreign_abi(id);
28492854
let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
28502855
let name = foreign::link_name(&*ni);
2851-
foreign::register_foreign_item_fn(ccx, abi, ty, &name)
2856+
let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name);
2857+
set_llvm_fn_attrs(ccx, &ni.attrs, llfn);
2858+
llfn
28522859
}
28532860
ast::ForeignItemStatic(..) => {
28542861
foreign::register_static(ccx, &*ni)

src/librustc_trans/trans/foreign.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,8 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
470470
"foreign fn's sty isn't a bare_fn_ty?")
471471
}
472472

473-
register_foreign_item_fn(ccx, abi, ty,
474-
&lname);
473+
let llfn = register_foreign_item_fn(ccx, abi, ty, &lname);
474+
base::set_llvm_fn_attrs(ccx, &foreign_item.attrs, llfn);
475475
// Unlike for other items, we shouldn't call
476476
// `base::update_linkage` here. Foreign items have
477477
// special linkage requirements, which are handled

src/libsyntax/feature_gate.rs

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
8383
("box_syntax", "1.0.0", Active),
8484
("on_unimplemented", "1.0.0", Active),
8585
("simd_ffi", "1.0.0", Active),
86+
("allocator", "1.0.0", Active),
8687

8788
("if_let", "1.0.0", Accepted),
8889
("while_let", "1.0.0", Accepted),
@@ -230,6 +231,8 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
230231
("rustc_on_unimplemented", Gated("on_unimplemented",
231232
"the `#[rustc_on_unimplemented]` attribute \
232233
is an experimental feature")),
234+
("allocator", Gated("allocator",
235+
"the `#[allocator]` attribute is an experimental feature")),
233236
("rustc_variance", Gated("rustc_attrs",
234237
"the `#[rustc_variance]` attribute \
235238
is an experimental feature")),

0 commit comments

Comments
 (0)