@@ -293,6 +293,9 @@ fn process_builtin_attrs(
293293 codegen_fn_attrs. linkage = linkage;
294294 }
295295 }
296+ AttributeKind :: Sanitize { span, .. } => {
297+ interesting_spans. sanitize = Some ( * span) ;
298+ }
296299 _ => { }
297300 }
298301 }
@@ -310,7 +313,6 @@ fn process_builtin_attrs(
310313 codegen_fn_attrs. flags |= CodegenFnAttrFlags :: ALLOCATOR_ZEROED
311314 }
312315 sym:: thread_local => codegen_fn_attrs. flags |= CodegenFnAttrFlags :: THREAD_LOCAL ,
313- sym:: sanitize => interesting_spans. sanitize = Some ( attr. span ( ) ) ,
314316 sym:: instruction_set => {
315317 codegen_fn_attrs. instruction_set = parse_instruction_set_attr ( tcx, attr)
316318 }
@@ -560,79 +562,9 @@ fn opt_trait_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
560562 }
561563}
562564
563- /// For an attr that has the `sanitize` attribute, read the list of
564- /// disabled sanitizers. `current_attr` holds the information about
565- /// previously parsed attributes.
566- fn parse_sanitize_attr (
567- tcx : TyCtxt < ' _ > ,
568- attr : & Attribute ,
569- current_attr : SanitizerSet ,
570- ) -> SanitizerSet {
571- let mut result = current_attr;
572- if let Some ( list) = attr. meta_item_list ( ) {
573- for item in list. iter ( ) {
574- let MetaItemInner :: MetaItem ( set) = item else {
575- tcx. dcx ( ) . emit_err ( errors:: InvalidSanitize { span : attr. span ( ) } ) ;
576- break ;
577- } ;
578- let segments = set. path . segments . iter ( ) . map ( |x| x. ident . name ) . collect :: < Vec < _ > > ( ) ;
579- match segments. as_slice ( ) {
580- // Similar to clang, sanitize(address = ..) and
581- // sanitize(kernel_address = ..) control both ASan and KASan
582- // Source: https://reviews.llvm.org/D44981.
583- [ sym:: address] | [ sym:: kernel_address] if set. value_str ( ) == Some ( sym:: off) => {
584- result |= SanitizerSet :: ADDRESS | SanitizerSet :: KERNELADDRESS
585- }
586- [ sym:: address] | [ sym:: kernel_address] if set. value_str ( ) == Some ( sym:: on) => {
587- result &= !SanitizerSet :: ADDRESS ;
588- result &= !SanitizerSet :: KERNELADDRESS ;
589- }
590- [ sym:: cfi] if set. value_str ( ) == Some ( sym:: off) => result |= SanitizerSet :: CFI ,
591- [ sym:: cfi] if set. value_str ( ) == Some ( sym:: on) => result &= !SanitizerSet :: CFI ,
592- [ sym:: kcfi] if set. value_str ( ) == Some ( sym:: off) => result |= SanitizerSet :: KCFI ,
593- [ sym:: kcfi] if set. value_str ( ) == Some ( sym:: on) => result &= !SanitizerSet :: KCFI ,
594- [ sym:: memory] if set. value_str ( ) == Some ( sym:: off) => {
595- result |= SanitizerSet :: MEMORY
596- }
597- [ sym:: memory] if set. value_str ( ) == Some ( sym:: on) => {
598- result &= !SanitizerSet :: MEMORY
599- }
600- [ sym:: memtag] if set. value_str ( ) == Some ( sym:: off) => {
601- result |= SanitizerSet :: MEMTAG
602- }
603- [ sym:: memtag] if set. value_str ( ) == Some ( sym:: on) => {
604- result &= !SanitizerSet :: MEMTAG
605- }
606- [ sym:: shadow_call_stack] if set. value_str ( ) == Some ( sym:: off) => {
607- result |= SanitizerSet :: SHADOWCALLSTACK
608- }
609- [ sym:: shadow_call_stack] if set. value_str ( ) == Some ( sym:: on) => {
610- result &= !SanitizerSet :: SHADOWCALLSTACK
611- }
612- [ sym:: thread] if set. value_str ( ) == Some ( sym:: off) => {
613- result |= SanitizerSet :: THREAD
614- }
615- [ sym:: thread] if set. value_str ( ) == Some ( sym:: on) => {
616- result &= !SanitizerSet :: THREAD
617- }
618- [ sym:: hwaddress] if set. value_str ( ) == Some ( sym:: off) => {
619- result |= SanitizerSet :: HWADDRESS
620- }
621- [ sym:: hwaddress] if set. value_str ( ) == Some ( sym:: on) => {
622- result &= !SanitizerSet :: HWADDRESS
623- }
624- _ => {
625- tcx. dcx ( ) . emit_err ( errors:: InvalidSanitize { span : attr. span ( ) } ) ;
626- }
627- }
628- }
629- }
630- result
631- }
632-
633565fn disabled_sanitizers_for ( tcx : TyCtxt < ' _ > , did : LocalDefId ) -> SanitizerSet {
634566 // Backtrack to the crate root.
635- let disabled = match tcx. opt_local_parent ( did) {
567+ let mut disabled = match tcx. opt_local_parent ( did) {
636568 // Check the parent (recursively).
637569 Some ( parent) => tcx. disabled_sanitizers_for ( parent) ,
638570 // We reached the crate root without seeing an attribute, so
@@ -641,8 +573,17 @@ fn disabled_sanitizers_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerSet {
641573 } ;
642574
643575 // Check for a sanitize annotation directly on this def.
644- if let Some ( attr) = tcx. get_attr ( did, sym:: sanitize) {
645- return parse_sanitize_attr ( tcx, attr, disabled) ;
576+ if let Some ( ( on_set, off_set) ) = find_attr ! ( tcx. get_all_attrs( did) , AttributeKind :: Sanitize { on_set, off_set, ..} => ( on_set, off_set) )
577+ {
578+ // the on set is the set of sanitizers explicitly enabled.
579+ // we mask those out since we want the set of disabled sanitizers here
580+ disabled &= !* on_set;
581+ // the off set is the set of sanitizers explicitly disabled.
582+ // we or those in here.
583+ disabled |= * off_set;
584+ // the on set and off set are distjoint since there's a third option: unset.
585+ // a node may not set the sanitizer setting in which case it inherits from parents.
586+ // the code above in this function does this backtracking
646587 }
647588 disabled
648589}
0 commit comments