1
+ // ignore-tidy-filelength
2
+
1
3
//! "Collection" is the process of determining the type and other external
2
4
//! details of each item in Rust. Collection is specifically concerned
3
5
//! with *inter-procedural* things -- for example, for a function
@@ -2743,6 +2745,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2743
2745
2744
2746
let mut inline_span = None ;
2745
2747
let mut link_ordinal_span = None ;
2748
+ let mut no_sanitize_span = None ;
2746
2749
for attr in attrs. iter ( ) {
2747
2750
if attr. check_name ( sym:: cold) {
2748
2751
codegen_fn_attrs. flags |= CodegenFnAttrFlags :: COLD ;
@@ -2832,6 +2835,24 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2832
2835
if let ordinal @ Some ( _) = check_link_ordinal ( tcx, attr) {
2833
2836
codegen_fn_attrs. link_ordinal = ordinal;
2834
2837
}
2838
+ } else if attr. check_name ( sym:: no_sanitize) {
2839
+ no_sanitize_span = Some ( attr. span ) ;
2840
+ if let Some ( list) = attr. meta_item_list ( ) {
2841
+ for item in list. iter ( ) {
2842
+ if item. check_name ( sym:: address) {
2843
+ codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_SANITIZE_ADDRESS ;
2844
+ } else if item. check_name ( sym:: memory) {
2845
+ codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_SANITIZE_MEMORY ;
2846
+ } else if item. check_name ( sym:: thread) {
2847
+ codegen_fn_attrs. flags |= CodegenFnAttrFlags :: NO_SANITIZE_THREAD ;
2848
+ } else {
2849
+ tcx. sess
2850
+ . struct_span_err ( item. span ( ) , "invalid argument for `no_sanitize`" )
2851
+ . note ( "expected one of: `address`, `memory` or `thread`" )
2852
+ . emit ( ) ;
2853
+ }
2854
+ }
2855
+ }
2835
2856
}
2836
2857
}
2837
2858
@@ -2911,7 +2932,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2911
2932
// purpose functions as they wouldn't have the right target features
2912
2933
// enabled. For that reason we also forbid #[inline(always)] as it can't be
2913
2934
// respected.
2914
-
2915
2935
if codegen_fn_attrs. target_features . len ( ) > 0 {
2916
2936
if codegen_fn_attrs. inline == InlineAttr :: Always {
2917
2937
if let Some ( span) = inline_span {
@@ -2924,6 +2944,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs {
2924
2944
}
2925
2945
}
2926
2946
2947
+ if codegen_fn_attrs. flags . intersects ( CodegenFnAttrFlags :: NO_SANITIZE_ANY ) {
2948
+ if codegen_fn_attrs. inline == InlineAttr :: Always {
2949
+ if let ( Some ( no_sanitize_span) , Some ( inline_span) ) = ( no_sanitize_span, inline_span) {
2950
+ let hir_id = tcx. hir ( ) . as_local_hir_id ( id) . unwrap ( ) ;
2951
+ tcx. struct_span_lint_hir (
2952
+ lint:: builtin:: INLINE_NO_SANITIZE ,
2953
+ hir_id,
2954
+ no_sanitize_span,
2955
+ "`no_sanitize` will have no effect after inlining" ,
2956
+ )
2957
+ . span_note ( inline_span, "inlining requested here" )
2958
+ . emit ( ) ;
2959
+ }
2960
+ }
2961
+ }
2962
+
2927
2963
// Weak lang items have the same semantics as "std internal" symbols in the
2928
2964
// sense that they're preserved through all our LTO passes and only
2929
2965
// strippable by the linker.
0 commit comments