@@ -275,6 +275,7 @@ fn arg_attrs_for_rust_scalar<'tcx>(
275275 offset : Size ,
276276 is_return : bool ,
277277 drop_target_pointee : Option < Ty < ' tcx > > ,
278+ involves_raw_ptr : bool ,
278279) -> ArgAttributes {
279280 let mut attrs = ArgAttributes :: new ( ) ;
280281
@@ -348,9 +349,10 @@ fn arg_attrs_for_rust_scalar<'tcx>(
348349 PointerKind :: MutableRef { unpin } => unpin && noalias_mut_ref,
349350 PointerKind :: Box { unpin, global } => unpin && global && noalias_for_box,
350351 } ;
352+
351353 // We can never add `noalias` in return position; that LLVM attribute has some very surprising semantics
352354 // (see <https://github.com/rust-lang/unsafe-code-guidelines/issues/385#issuecomment-1368055745>).
353- if no_alias && !is_return {
355+ if no_alias && !involves_raw_ptr && ! is_return {
354356 attrs. set ( ArgAttribute :: NoAlias ) ;
355357 }
356358
@@ -509,6 +511,14 @@ fn fn_abi_new_uncached<'tcx>(
509511 extra_args
510512 } ;
511513
514+ let involves_raw_ptr = inputs
515+ . iter ( )
516+ . copied ( )
517+ . chain ( extra_args. iter ( ) . copied ( ) )
518+ . chain ( caller_location)
519+ . chain ( Some ( sig. output ( ) ) )
520+ . any ( |ty| matches ! ( ty. kind( ) , ty:: RawPtr ( _, _) ) ) ;
521+
512522 let is_drop_in_place = determined_fn_def_id. is_some_and ( |def_id| {
513523 tcx. is_lang_item ( def_id, LangItem :: DropInPlace )
514524 || tcx. is_lang_item ( def_id, LangItem :: AsyncDropInPlace )
@@ -535,7 +545,15 @@ fn fn_abi_new_uncached<'tcx>(
535545 } ;
536546
537547 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)
548+ arg_attrs_for_rust_scalar (
549+ * cx,
550+ scalar,
551+ * layout,
552+ offset,
553+ is_return,
554+ drop_target_pointee,
555+ involves_raw_ptr,
556+ )
539557 } ) ;
540558
541559 if arg. layout . is_zst ( ) {
0 commit comments