about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-08-16 11:21:11 +0000
committerbors <bors@rust-lang.org>2014-08-16 11:21:11 +0000
commitcf71f1c7b077c93b33360fd5af6442fff2e39876 (patch)
treefc4a96829918a5d83bdfdb1e3d69739e451cf131
parentec9476cd63af58d55e552532d14040d972392bd6 (diff)
parent48edb32a3fc8ba6cc3db9a9d11f5201a919391f5 (diff)
downloadrust-cf71f1c7b077c93b33360fd5af6442fff2e39876.tar.gz
rust-cf71f1c7b077c93b33360fd5af6442fff2e39876.zip
auto merge of #16525 : thestinger/rust/readonly, r=pcwalton
These are already marked as `noalias` due to the immutability guarantee
(see 4c2d4cd3dea344e81e4df24382ac3f23e2f86f40), but more information can
be bubbled up to the caller via `readonly`.
-rw-r--r--src/librustc/middle/trans/base.rs12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 896d37669e6..8ea99a5cad3 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2278,7 +2278,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(_) => {
@@ -2354,8 +2354,10 @@ 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() => {
 
@@ -2363,6 +2365,10 @@ pub fn get_fn_llvm_attributes(ccx: &CrateContext, fn_ty: ty::t)
                 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);