@@ -2743,6 +2743,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
27432743
27442744 let mut inline_span = None ;
27452745 let mut link_ordinal_span = None ;
2746+ let mut no_sanitize_span = None ;
27462747 for attr in attrs. iter ( ) {
27472748 if attr. check_name ( sym:: cold) {
27482749 codegen_fn_attrs. flags |= CodegenFnAttrFlags :: COLD ;
@@ -2832,6 +2833,24 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
28322833 if let ordinal @ Some ( _) = check_link_ordinal ( tcx, attr) {
28332834 codegen_fn_attrs. link_ordinal = ordinal;
28342835 }
2836+ } else if attr. check_name ( sym:: no_sanitize) {
2837+ no_sanitize_span = Some ( attr. span ) ;
2838+ if let Some ( list) = attr. meta_item_list ( ) {
2839+ for item in list. iter ( ) {
2840+ if item. check_name ( sym:: address) {
2841+ codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_SANITIZE_ADDRESS ;
2842+ } else if item. check_name ( sym:: memory) {
2843+ codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_SANITIZE_MEMORY ;
2844+ } else if item. check_name ( sym:: thread) {
2845+ codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_SANITIZE_THREAD ;
2846+ } else {
2847+ tcx. sess
2848+ . struct_span_err ( item. span ( ) , "invalid argument for `no_sanitize`" )
2849+ . note ( "expected one of: `address`, `memory` or `thread`" )
2850+ . emit ( ) ;
2851+ }
2852+ }
2853+ }
28352854 }
28362855 }
28372856
@@ -2911,7 +2930,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
29112930 // purpose functions as they wouldn't have the right target features
29122931 // enabled. For that reason we also forbid #[inline(always)] as it can't be
29132932 // respected.
2914-
29152933 if codegen_fn_attrs. target_features . len ( ) > 0 {
29162934 if codegen_fn_attrs. inline == InlineAttr :: Always {
29172935 if let Some ( span) = inline_span {
@@ -2924,6 +2942,25 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
29242942 }
29252943 }
29262944
2945+ let no_sanitize_flags = CodegenFnAttrFlags :: NO_SANITIZE_ADDRESS
2946+ | CodegenFnAttrFlags :: NO_SANITIZE_MEMORY
2947+ | CodegenFnAttrFlags :: NO_SANITIZE_THREAD ;
2948+ if codegen_fn_attrs. flags . intersects ( no_sanitize_flags) {
2949+ if codegen_fn_attrs. inline == InlineAttr :: Always {
2950+ if let ( Some ( no_sanitize_span) , Some ( inline_span) ) = ( no_sanitize_span, inline_span) {
2951+ let hir_id = tcx. hir ( ) . as_local_hir_id ( id) . unwrap ( ) ;
2952+ tcx. struct_span_lint_hir (
2953+ lint:: builtin:: INLINE_NO_SANITIZE ,
2954+ hir_id,
2955+ no_sanitize_span,
2956+ "`no_sanitize` will have no effect after inlining" ,
2957+ )
2958+ . span_note ( inline_span, "inlining requested here" )
2959+ . emit ( ) ;
2960+ }
2961+ }
2962+ }
2963+
29272964 // Weak lang items have the same semantics as "std internal" symbols in the
29282965 // sense that they're preserved through all our LTO passes and only
29292966 // strippable by the linker.
0 commit comments