@@ -262,41 +262,35 @@ pub fn from_fn_type<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_type: ty::Ty<'tcx
262
262
. arg ( idx, llvm:: DereferenceableAttribute ( llsz) ) ;
263
263
}
264
264
265
- // `&mut` pointer parameters never alias other parameters, or mutable global data
266
- //
267
- // `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as both
268
- // `readonly` and `noalias`, as LLVM's definition of `noalias ` is based solely on
269
- // memory dependencies rather than pointer equality
270
- ty :: TyRef ( b , mt ) if mt . mutbl == ast :: MutMutable ||
271
- ! ty:: type_contents ( ccx. tcx ( ) , mt. ty ) . interior_unsafe ( ) => {
272
-
273
- let llsz = machine :: llsize_of_real ( ccx , type_of :: type_of ( ccx , mt . ty ) ) ;
274
- attrs. arg ( idx, llvm:: Attribute :: NoAlias )
275
- . arg ( idx , llvm :: DereferenceableAttribute ( llsz ) ) ;
265
+ ty :: TyRef ( b , mt ) => {
266
+ // `&mut` pointer parameters never alias other parameters, or mutable global data
267
+ //
268
+ // `&T` where `T` contains no `UnsafeCell<U> ` is immutable, and can be marked as
269
+ // both `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely
270
+ // on memory dependencies rather than pointer equality
271
+ let interior_unsafe = ty:: type_contents ( ccx. tcx ( ) , mt. ty ) . interior_unsafe ( ) ;
272
+
273
+ if mt . mutbl == ast :: MutMutable || !interior_unsafe {
274
+ attrs. arg ( idx, llvm:: Attribute :: NoAlias ) ;
275
+ }
276
276
277
- if mt. mutbl == ast:: MutImmutable {
277
+ if mt. mutbl == ast:: MutImmutable && !interior_unsafe {
278
278
attrs. arg ( idx, llvm:: Attribute :: ReadOnly ) ;
279
279
}
280
280
281
+ // & pointer parameters are also never null and we know exactly
282
+ // how many bytes we can dereference
283
+ let llsz = machine:: llsize_of_real ( ccx, type_of:: type_of ( ccx, mt. ty ) ) ;
284
+ attrs. arg ( idx, llvm:: DereferenceableAttribute ( llsz) ) ;
285
+
286
+ // When a reference in an argument has no named lifetime, it's
287
+ // impossible for that reference to escape this function
288
+ // (returned or stored beyond the call by a closure).
281
289
if let ReLateBound ( _, BrAnon ( _) ) = * b {
282
290
attrs. arg ( idx, llvm:: Attribute :: NoCapture ) ;
283
291
}
284
292
}
285
293
286
- // When a reference in an argument has no named lifetime, it's impossible for that
287
- // reference to escape this function (returned or stored beyond the call by a closure).
288
- ty:: TyRef ( & ReLateBound ( _, BrAnon ( _) ) , mt) => {
289
- let llsz = machine:: llsize_of_real ( ccx, type_of:: type_of ( ccx, mt. ty ) ) ;
290
- attrs. arg ( idx, llvm:: Attribute :: NoCapture )
291
- . arg ( idx, llvm:: DereferenceableAttribute ( llsz) ) ;
292
- }
293
-
294
- // & pointer parameters are also never null and we know exactly how
295
- // many bytes we can dereference
296
- ty:: TyRef ( _, mt) => {
297
- let llsz = machine:: llsize_of_real ( ccx, type_of:: type_of ( ccx, mt. ty ) ) ;
298
- attrs. arg ( idx, llvm:: DereferenceableAttribute ( llsz) ) ;
299
- }
300
294
_ => ( )
301
295
}
302
296
}
0 commit comments