Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2280,7 +2280,7 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
match ty::get(ret_ty).sty {
// `~` pointer return values never alias because ownership
// is transferred
ty::ty_uniq(it) if match ty::get(it).sty {
ty::ty_uniq(it) if match ty::get(it).sty {
ty::ty_str | ty::ty_vec(..) | ty::ty_trait(..) => true, _ => false
} => {}
ty::ty_uniq(_) => {
Expand Down Expand Up @@ -2356,15 +2356,21 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
}

// `&mut` pointer parameters never alias other parameters, or mutable global data
// `&` pointer parameters never alias either (for LLVM's purposes) as long as the
// interior is safe
//
// `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as both
// `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely on
// memory dependencies rather than pointer equality
ty::ty_rptr(b, mt) if mt.mutbl == ast::MutMutable ||
!ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe() => {

let llsz = llsize_of_real(ccx, type_of::type_of(ccx, mt.ty));
attrs.arg(idx, llvm::NoAliasAttribute)
.arg(idx, llvm::DereferenceableAttribute(llsz));

if mt.mutbl == ast::MutImmutable {
attrs.arg(idx, llvm::ReadOnlyAttribute);
}

match b {
ReLateBound(_, BrAnon(_)) => {
attrs.arg(idx, llvm::NoCaptureAttribute);
Expand Down