@@ -275,6 +275,8 @@ fn arg_attrs_for_rust_scalar<'tcx>(
275275 offset : Size ,
276276 is_return : bool ,
277277 drop_target_pointee : Option < Ty < ' tcx > > ,
278+ mut involves_raw_ptr : bool ,
279+ _instance : Option < ty:: Instance < ' tcx > > ,
278280) -> ArgAttributes {
279281 let mut attrs = ArgAttributes :: new ( ) ;
280282
@@ -305,6 +307,7 @@ fn arg_attrs_for_rust_scalar<'tcx>(
305307 Some ( kind)
306308 } else if let Some ( pointee) = drop_target_pointee {
307309 // The argument to `drop_in_place` is semantically equivalent to a mutable reference.
310+ involves_raw_ptr = false ;
308311 Some ( PointerKind :: MutableRef { unpin : pointee. is_unpin ( tcx, cx. typing_env ) } )
309312 } else {
310313 None
@@ -348,12 +351,17 @@ fn arg_attrs_for_rust_scalar<'tcx>(
348351 PointerKind :: MutableRef { unpin } => unpin && noalias_mut_ref,
349352 PointerKind :: Box { unpin, global } => unpin && global && noalias_for_box,
350353 } ;
354+
351355 // We can never add `noalias` in return position; that LLVM attribute has some very surprising semantics
352356 // (see <https://github.com/rust-lang/unsafe-code-guidelines/issues/385#issuecomment-1368055745>).
353- if no_alias && !is_return {
357+ if no_alias && !involves_raw_ptr && ! is_return {
354358 attrs. set ( ArgAttribute :: NoAlias ) ;
355359 }
356360
361+ //if no_alias && involves_raw_ptr && !is_return {
362+ // println!("xxxxxxx {instance:?}\nyyyyyyy {:?}", layout.ty);
363+ //}
364+
357365 if matches ! ( kind, PointerKind :: SharedRef { frozen: true } ) && !is_return {
358366 attrs. set ( ArgAttribute :: ReadOnly ) ;
359367 attrs. set ( ArgAttribute :: CapturesReadOnly ) ;
@@ -509,6 +517,14 @@ fn fn_abi_new_uncached<'tcx>(
509517 extra_args
510518 } ;
511519
520+ let involves_raw_ptr = inputs
521+ . iter ( )
522+ . copied ( )
523+ . chain ( extra_args. iter ( ) . copied ( ) )
524+ . chain ( caller_location)
525+ . chain ( Some ( sig. output ( ) ) )
526+ . any ( |ty| matches ! ( ty. kind( ) , ty:: RawPtr ( _, _) ) ) ;
527+
512528 let is_drop_in_place = determined_fn_def_id. is_some_and ( |def_id| {
513529 tcx. is_lang_item ( def_id, LangItem :: DropInPlace )
514530 || tcx. is_lang_item ( def_id, LangItem :: AsyncDropInPlace )
@@ -518,6 +534,7 @@ fn fn_abi_new_uncached<'tcx>(
518534 let span = tracing:: debug_span!( "arg_of" ) ;
519535 let _entered = span. enter ( ) ;
520536 let is_return = arg_idx. is_none ( ) ;
537+ let is_caller_location = arg_idx. is_some_and ( |i| i >= inputs. len ( ) + extra_args. len ( ) ) ;
521538 let is_drop_target = is_drop_in_place && arg_idx == Some ( 0 ) ;
522539 let drop_target_pointee = is_drop_target. then ( || match ty. kind ( ) {
523540 ty:: RawPtr ( ty, _) => * ty,
@@ -535,7 +552,16 @@ fn fn_abi_new_uncached<'tcx>(
535552 } ;
536553
537554 let mut arg = ArgAbi :: new ( cx, layout, |layout, scalar, offset| {
538- arg_attrs_for_rust_scalar ( * cx, scalar, * layout, offset, is_return, drop_target_pointee)
555+ arg_attrs_for_rust_scalar (
556+ * cx,
557+ scalar,
558+ * layout,
559+ offset,
560+ is_return,
561+ drop_target_pointee,
562+ involves_raw_ptr && !is_caller_location,
563+ instance,
564+ )
539565 } ) ;
540566
541567 if arg. layout . is_zst ( ) {
0 commit comments