@@ -83,10 +83,69 @@ pub struct TargetModifier {
8383 pub value_name : String ,
8484}
8585
86+ mod target_modifier_consistency_check {
87+ use super :: * ;
88+ pub ( super ) fn sanitizer ( l : & TargetModifier , r : & TargetModifier ) -> bool {
89+ let mut lparsed: SanitizerSet = Default :: default ( ) ;
90+ let lval = if l. value_name . is_empty ( ) { None } else { Some ( l. value_name . as_str ( ) ) } ;
91+ parse:: parse_sanitizers ( & mut lparsed, lval) ;
92+
93+ let mut rparsed: SanitizerSet = Default :: default ( ) ;
94+ let rval = if r. value_name . is_empty ( ) { None } else { Some ( r. value_name . as_str ( ) ) } ;
95+ parse:: parse_sanitizers ( & mut rparsed, rval) ;
96+
97+ // Some sanitizers need to be target modifiers, and some do not.
98+ // For now, we should mark all sanitizers as target modifiers except for these:
99+ // AddressSanitizer, LeakSanitizer
100+ let tmod_sanitizers = SanitizerSet :: MEMORY
101+ | SanitizerSet :: THREAD
102+ | SanitizerSet :: HWADDRESS
103+ | SanitizerSet :: CFI
104+ | SanitizerSet :: MEMTAG
105+ | SanitizerSet :: SHADOWCALLSTACK
106+ | SanitizerSet :: KCFI
107+ | SanitizerSet :: KERNELADDRESS
108+ | SanitizerSet :: SAFESTACK
109+ | SanitizerSet :: DATAFLOW ;
110+
111+ lparsed & tmod_sanitizers == rparsed & tmod_sanitizers
112+ }
113+ pub ( super ) fn sanitizer_cfi_normalize_integers (
114+ opts : & Options ,
115+ l : & TargetModifier ,
116+ r : & TargetModifier ,
117+ ) -> bool {
118+ // For kCFI, the helper flag -Zsanitizer-cfi-normalize-integers should also be a target modifier
119+ if opts. unstable_opts . sanitizer . contains ( SanitizerSet :: KCFI ) {
120+ return l. extend ( ) . tech_value == r. extend ( ) . tech_value ;
121+ }
122+ true
123+ }
124+ }
125+
86126impl TargetModifier {
87127 pub fn extend ( & self ) -> ExtendedTargetModifierInfo {
88128 self . opt . reparse ( & self . value_name )
89129 }
130+ // Custom consistency check for target modifiers (or default `l.tech_value == r.tech_value`)
131+ pub fn consistent ( & self , opts : & Options , other : & TargetModifier ) -> bool {
132+ assert ! ( self . opt == other. opt) ;
133+ match self . opt {
134+ OptionsTargetModifiers :: UnstableOptions ( unstable) => match unstable {
135+ UnstableOptionsTargetModifiers :: sanitizer => {
136+ return target_modifier_consistency_check:: sanitizer ( self , other) ;
137+ }
138+ UnstableOptionsTargetModifiers :: sanitizer_cfi_normalize_integers => {
139+ return target_modifier_consistency_check:: sanitizer_cfi_normalize_integers (
140+ opts, self , other,
141+ ) ;
142+ }
143+ _ => { }
144+ } ,
145+ _ => { }
146+ } ;
147+ self . extend ( ) . tech_value == other. extend ( ) . tech_value
148+ }
90149}
91150
92151fn tmod_push_impl (
@@ -2427,13 +2486,13 @@ options! {
24272486 remark_dir: Option <PathBuf > = ( None , parse_opt_pathbuf, [ UNTRACKED ] ,
24282487 "directory into which to write optimization remarks (if not specified, they will be \
24292488 written to standard error output)") ,
2430- sanitizer: SanitizerSet = ( SanitizerSet :: empty( ) , parse_sanitizers, [ TRACKED ] ,
2489+ sanitizer: SanitizerSet = ( SanitizerSet :: empty( ) , parse_sanitizers, [ TRACKED TARGET_MODIFIER ] ,
24312490 "use a sanitizer" ) ,
24322491 sanitizer_cfi_canonical_jump_tables: Option <bool > = ( Some ( true ) , parse_opt_bool, [ TRACKED ] ,
24332492 "enable canonical jump tables (default: yes)" ) ,
24342493 sanitizer_cfi_generalize_pointers: Option <bool > = ( None , parse_opt_bool, [ TRACKED ] ,
24352494 "enable generalizing pointer types (default: no)" ) ,
2436- sanitizer_cfi_normalize_integers: Option <bool > = ( None , parse_opt_bool, [ TRACKED ] ,
2495+ sanitizer_cfi_normalize_integers: Option <bool > = ( None , parse_opt_bool, [ TRACKED TARGET_MODIFIER ] ,
24372496 "enable normalizing integer types (default: no)" ) ,
24382497 sanitizer_dataflow_abilist: Vec <String > = ( Vec :: new( ) , parse_comma_list, [ TRACKED ] ,
24392498 "additional ABI list files that control how shadow parameters are passed (comma separated)" ) ,
0 commit comments