Skip to content

Commit 7fbcdf6

Browse files
committed
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
1 parent 2c05354 commit 7fbcdf6

File tree

2 files changed

+5
-21
lines changed

2 files changed

+5
-21
lines changed

src/librustc_trans/trans/base.rs

+2-16
Original file line numberDiff line numberDiff line change
@@ -2490,29 +2490,15 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
24902490
if type_of::return_uses_outptr(ccx, ret_ty) {
24912491
let llret_sz = llsize_of_real(ccx, type_of::type_of(ccx, ret_ty));
24922492

2493-
// The outptr can be noalias and nocapture because it's entirely
2494-
// invisible to the program. We also know it's nonnull as well
2495-
// as how many bytes we can dereference
2493+
// The outptr can be nocapture because it's entirely invisible to the program. We also
2494+
// know it's nonnull as well as how many bytes we can dereference
24962495
attrs.arg(1, llvm::StructRetAttribute)
2497-
.arg(1, llvm::NoAliasAttribute)
24982496
.arg(1, llvm::NoCaptureAttribute)
24992497
.arg(1, llvm::DereferenceableAttribute(llret_sz));
25002498

25012499
// Add one more since there's an outptr
25022500
first_arg_offset += 1;
25032501
} else {
2504-
// The `noalias` attribute on the return value is useful to a
2505-
// function ptr caller.
2506-
match ret_ty.sty {
2507-
// `~` pointer return values never alias because ownership
2508-
// is transferred
2509-
ty::ty_uniq(it) if !common::type_is_sized(ccx.tcx(), it) => {}
2510-
ty::ty_uniq(_) => {
2511-
attrs.ret(llvm::NoAliasAttribute);
2512-
}
2513-
_ => {}
2514-
}
2515-
25162502
// We can also mark the return value as `dereferenceable` in certain cases
25172503
match ret_ty.sty {
25182504
// These are not really pointers but pairs, (pointer, len)

src/librustc_trans/trans/foreign.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -336,11 +336,9 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
336336
if fn_type.ret_ty.is_indirect() {
337337
let llret_sz = machine::llsize_of_real(ccx, fn_type.ret_ty.ty);
338338

339-
// The outptr can be noalias and nocapture because it's entirely
340-
// invisible to the program. We also know it's nonnull as well
341-
// as how many bytes we can dereference
342-
attrs.arg(1, llvm::NoAliasAttribute)
343-
.arg(1, llvm::NoCaptureAttribute)
339+
// The outptr can be nocapture because it's entirely invisible to the program. We also know
340+
// it's nonnull as well as how many bytes we can dereference
341+
attrs.arg(1, llvm::NoCaptureAttribute)
344342
.arg(1, llvm::DereferenceableAttribute(llret_sz));
345343
};
346344

0 commit comments

Comments
 (0)