From 7fbcdf63cf020be157643e629903892f4b902c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Fri, 6 Feb 2015 20:53:18 +0100 Subject: [PATCH] Remove `noalias` on return values On return values `noalias` has a stricter meaning than on arguments. It means that the function is malloc-like. To quote the LLVM docs: Furthermore, the semantics of the noalias attribute on return values are stronger than the semantics of the attribute when used on function arguments. On function return values, the noalias attribute indicates that the function acts like a system memory allocation function, returning a pointer to allocated storage disjoint from the storage for any other object accessible to the caller. We use it for all kinds of functions, which is wrong, so let's stop doing that. Fixes #21996 --- src/librustc_trans/trans/base.rs | 18 ++---------------- src/librustc_trans/trans/foreign.rs | 8 +++----- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 062a21dffa8ad..69074c2933e40 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -2490,29 +2490,15 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty< if type_of::return_uses_outptr(ccx, ret_ty) { let llret_sz = llsize_of_real(ccx, type_of::type_of(ccx, ret_ty)); - // The outptr can be noalias and nocapture because it's entirely - // invisible to the program. We also know it's nonnull as well - // as how many bytes we can dereference + // The outptr can be nocapture because it's entirely invisible to the program. We also + // know it's nonnull as well as how many bytes we can dereference attrs.arg(1, llvm::StructRetAttribute) - .arg(1, llvm::NoAliasAttribute) .arg(1, llvm::NoCaptureAttribute) .arg(1, llvm::DereferenceableAttribute(llret_sz)); // Add one more since there's an outptr first_arg_offset += 1; } else { - // The `noalias` attribute on the return value is useful to a - // function ptr caller. - match ret_ty.sty { - // `~` pointer return values never alias because ownership - // is transferred - ty::ty_uniq(it) if !common::type_is_sized(ccx.tcx(), it) => {} - ty::ty_uniq(_) => { - attrs.ret(llvm::NoAliasAttribute); - } - _ => {} - } - // We can also mark the return value as `dereferenceable` in certain cases match ret_ty.sty { // These are not really pointers but pairs, (pointer, len) diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index f2d80f36297f7..de1f168d7a8e8 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -336,11 +336,9 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, if fn_type.ret_ty.is_indirect() { let llret_sz = machine::llsize_of_real(ccx, fn_type.ret_ty.ty); - // The outptr can be noalias and nocapture because it's entirely - // invisible to the program. We also know it's nonnull as well - // as how many bytes we can dereference - attrs.arg(1, llvm::NoAliasAttribute) - .arg(1, llvm::NoCaptureAttribute) + // The outptr can be nocapture because it's entirely invisible to the program. We also know + // it's nonnull as well as how many bytes we can dereference + attrs.arg(1, llvm::NoCaptureAttribute) .arg(1, llvm::DereferenceableAttribute(llret_sz)); };