@@ -83,10 +83,77 @@ 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 : Option < & 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 = r. filter ( |v| !v. value_name . is_empty ( ) ) . map ( |v| v. 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 : Option < & 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+ if let Some ( r) = r {
121+ return l. extend ( ) . tech_value == r. extend ( ) . tech_value ;
122+ } else {
123+ return false ;
124+ }
125+ }
126+ true
127+ }
128+ }
129+
86130impl TargetModifier {
87131 pub fn extend ( & self ) -> ExtendedTargetModifierInfo {
88132 self . opt . reparse ( & self . value_name )
89133 }
134+ // Custom consistency check for target modifiers (or default `l.tech_value == r.tech_value`)
135+ // When other is None, consistency with default value is checked
136+ pub fn consistent ( & self , opts : & Options , other : Option < & TargetModifier > ) -> bool {
137+ assert ! ( other. is_none( ) || self . opt == other. unwrap( ) . opt) ;
138+ match self . opt {
139+ OptionsTargetModifiers :: UnstableOptions ( unstable) => match unstable {
140+ UnstableOptionsTargetModifiers :: sanitizer => {
141+ return target_modifier_consistency_check:: sanitizer ( self , other) ;
142+ }
143+ UnstableOptionsTargetModifiers :: sanitizer_cfi_normalize_integers => {
144+ return target_modifier_consistency_check:: sanitizer_cfi_normalize_integers (
145+ opts, self , other,
146+ ) ;
147+ }
148+ _ => { }
149+ } ,
150+ _ => { }
151+ } ;
152+ match other {
153+ Some ( other) => self . extend ( ) . tech_value == other. extend ( ) . tech_value ,
154+ None => false ,
155+ }
156+ }
90157}
91158
92159fn tmod_push_impl (
@@ -2427,13 +2494,13 @@ options! {
24272494 remark_dir: Option <PathBuf > = ( None , parse_opt_pathbuf, [ UNTRACKED ] ,
24282495 "directory into which to write optimization remarks (if not specified, they will be \
24292496 written to standard error output)") ,
2430- sanitizer: SanitizerSet = ( SanitizerSet :: empty( ) , parse_sanitizers, [ TRACKED ] ,
2497+ sanitizer: SanitizerSet = ( SanitizerSet :: empty( ) , parse_sanitizers, [ TRACKED TARGET_MODIFIER ] ,
24312498 "use a sanitizer" ) ,
24322499 sanitizer_cfi_canonical_jump_tables: Option <bool > = ( Some ( true ) , parse_opt_bool, [ TRACKED ] ,
24332500 "enable canonical jump tables (default: yes)" ) ,
24342501 sanitizer_cfi_generalize_pointers: Option <bool > = ( None , parse_opt_bool, [ TRACKED ] ,
24352502 "enable generalizing pointer types (default: no)" ) ,
2436- sanitizer_cfi_normalize_integers: Option <bool > = ( None , parse_opt_bool, [ TRACKED ] ,
2503+ sanitizer_cfi_normalize_integers: Option <bool > = ( None , parse_opt_bool, [ TRACKED TARGET_MODIFIER ] ,
24372504 "enable normalizing integer types (default: no)" ) ,
24382505 sanitizer_dataflow_abilist: Vec <String > = ( Vec :: new( ) , parse_comma_list, [ TRACKED ] ,
24392506 "additional ABI list files that control how shadow parameters are passed (comma separated)" ) ,
0 commit comments