diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index 3b93171386a..f9936b7a16a 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -198,6 +198,7 @@ mod imp { extern {} extern { + #[allocator] fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void; fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 5c9a42a8a71..34c0686fe37 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -69,6 +69,7 @@ #![feature(no_std)] #![no_std] +#![feature(allocator)] #![feature(lang_items, unsafe_destructor)] #![feature(box_syntax)] #![feature(optin_builtin_traits)] diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 74326d4ea91..ccf24f7e859 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -33,7 +33,7 @@ use back::link::{mangle_exported_name}; use back::{link, abi}; use lint; -use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param}; +use llvm::{AttrHelper, BasicBlockRef, Linkage, ValueRef, Vector, get_param}; use llvm; use metadata::{csearch, encoder, loader}; use middle::astencode; @@ -456,6 +456,9 @@ pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: Val llvm::FunctionIndex as c_uint, llvm::ColdAttribute as uint64_t) }, + "allocator" => { + llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn); + } _ => used = false, } if used { @@ -903,8 +906,10 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ccx.sess().bug("unexpected intrinsic in trans_external_path") } _ => { - foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, - &name[..]) + let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name[..]); + let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did); + set_llvm_fn_attrs(ccx, &attrs, llfn); + llfn } } } @@ -2841,7 +2846,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef { let abi = ccx.tcx().map.get_foreign_abi(id); let ty = ty::node_id_to_type(ccx.tcx(), ni.id); let name = foreign::link_name(&*ni); - foreign::register_foreign_item_fn(ccx, abi, ty, &name) + let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name); + set_llvm_fn_attrs(ccx, &ni.attrs, llfn); + llfn } ast::ForeignItemStatic(..) => { foreign::register_static(ccx, &*ni) diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index b0383e355e4..dfc7e7f604f 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -470,8 +470,8 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) { "foreign fn's sty isn't a bare_fn_ty?") } - register_foreign_item_fn(ccx, abi, ty, - &lname); + let llfn = register_foreign_item_fn(ccx, abi, ty, &lname); + base::set_llvm_fn_attrs(ccx, &foreign_item.attrs, llfn); // Unlike for other items, we shouldn't call // `base::update_linkage` here. Foreign items have // special linkage requirements, which are handled diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index c3bac0cf57c..0a9980c8925 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -83,6 +83,7 @@ ("box_syntax", "1.0.0", Active), ("on_unimplemented", "1.0.0", Active), ("simd_ffi", "1.0.0", Active), + ("allocator", "1.0.0", Active), ("if_let", "1.0.0", Accepted), ("while_let", "1.0.0", Accepted), @@ -230,6 +231,8 @@ enum Status { ("rustc_on_unimplemented", Gated("on_unimplemented", "the `#[rustc_on_unimplemented]` attribute \ is an experimental feature")), + ("allocator", Gated("allocator", + "the `#[allocator]` attribute is an experimental feature")), ("rustc_variance", Gated("rustc_attrs", "the `#[rustc_variance]` attribute \ is an experimental feature")),