@@ -600,19 +600,28 @@ bitflags::bitflags! {
600600 }
601601}
602602
603+ impl SanitizerSet {
604+ /// Return sanitizer's name
605+ ///
606+ /// Returns none if the flags is a set of sanitizers numbering not exactly one.
607+ fn as_str ( self ) -> Option < & ' static str > {
608+ Some ( match self {
609+ SanitizerSet :: ADDRESS => "address" ,
610+ SanitizerSet :: LEAK => "leak" ,
611+ SanitizerSet :: MEMORY => "memory" ,
612+ SanitizerSet :: THREAD => "thread" ,
613+ SanitizerSet :: HWADDRESS => "hwaddress" ,
614+ _ => return None ,
615+ } )
616+ }
617+ }
618+
603619/// Formats a sanitizer set as a comma separated list of sanitizers' names.
604620impl fmt:: Display for SanitizerSet {
605621 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
606622 let mut first = true ;
607623 for s in * self {
608- let name = match s {
609- SanitizerSet :: ADDRESS => "address" ,
610- SanitizerSet :: LEAK => "leak" ,
611- SanitizerSet :: MEMORY => "memory" ,
612- SanitizerSet :: THREAD => "thread" ,
613- SanitizerSet :: HWADDRESS => "hwaddress" ,
614- _ => panic ! ( "unrecognized sanitizer {:?}" , s) ,
615- } ;
624+ let name = s. as_str ( ) . unwrap_or_else ( || panic ! ( "unrecognized sanitizer {:?}" , s) ) ;
616625 if !first {
617626 f. write_str ( ", " ) ?;
618627 }
@@ -628,12 +637,18 @@ impl IntoIterator for SanitizerSet {
628637 type IntoIter = std:: vec:: IntoIter < SanitizerSet > ;
629638
630639 fn into_iter ( self ) -> Self :: IntoIter {
631- [ SanitizerSet :: ADDRESS , SanitizerSet :: LEAK , SanitizerSet :: MEMORY , SanitizerSet :: THREAD , SanitizerSet :: HWADDRESS ]
632- . iter ( )
633- . copied ( )
634- . filter ( |& s| self . contains ( s) )
635- . collect :: < Vec < _ > > ( )
636- . into_iter ( )
640+ [
641+ SanitizerSet :: ADDRESS ,
642+ SanitizerSet :: LEAK ,
643+ SanitizerSet :: MEMORY ,
644+ SanitizerSet :: THREAD ,
645+ SanitizerSet :: HWADDRESS ,
646+ ]
647+ . iter ( )
648+ . copied ( )
649+ . filter ( |& s| self . contains ( s) )
650+ . collect :: < Vec < _ > > ( )
651+ . into_iter ( )
637652 }
638653}
639654
@@ -643,6 +658,16 @@ impl<CTX> HashStable<CTX> for SanitizerSet {
643658 }
644659}
645660
661+ impl ToJson for SanitizerSet {
662+ fn to_json ( & self ) -> Json {
663+ self . into_iter ( )
664+ . map ( |v| Some ( v. as_str ( ) ?. to_json ( ) ) )
665+ . collect :: < Option < Vec < _ > > > ( )
666+ . unwrap_or ( Vec :: new ( ) )
667+ . to_json ( )
668+ }
669+ }
670+
646671macro_rules! supported_targets {
647672 ( $( ( $( $triple: literal, ) + $module: ident ) , ) + ) => {
648673 $( mod $module; ) +
@@ -1614,6 +1639,24 @@ impl Target {
16141639 ) ) ,
16151640 } ) . unwrap_or( Ok ( ( ) ) )
16161641 } ) ;
1642+ ( $key_name: ident, SanitizerSet ) => ( {
1643+ let name = ( stringify!( $key_name) ) . replace( "_" , "-" ) ;
1644+ obj. find( & name[ ..] ) . and_then( |o| o. as_array( ) ) . and_then( |a| {
1645+ for s in a {
1646+ base. $key_name |= match s. as_string( ) {
1647+ Some ( "address" ) => SanitizerSet :: ADDRESS ,
1648+ Some ( "leak" ) => SanitizerSet :: LEAK ,
1649+ Some ( "memory" ) => SanitizerSet :: MEMORY ,
1650+ Some ( "thread" ) => SanitizerSet :: THREAD ,
1651+ Some ( "hwaddress" ) => SanitizerSet :: HWADDRESS ,
1652+ Some ( s) => return Some ( Err ( format!( "unknown sanitizer {}" , s) ) ) ,
1653+ _ => return Some ( Err ( format!( "not a string: {:?}" , s) ) ) ,
1654+ } ;
1655+ }
1656+ Some ( Ok ( ( ) ) )
1657+ } ) . unwrap_or( Ok ( ( ) ) )
1658+ } ) ;
1659+
16171660 ( $key_name: ident, crt_objects_fallback) => ( {
16181661 let name = ( stringify!( $key_name) ) . replace( "_" , "-" ) ;
16191662 obj. find( & name[ ..] ) . and_then( |o| o. as_string( ) . and_then( |s| {
@@ -1792,6 +1835,7 @@ impl Target {
17921835 key ! ( eh_frame_header, bool ) ;
17931836 key ! ( has_thumb_interworking, bool ) ;
17941837 key ! ( split_debuginfo, SplitDebuginfo ) ?;
1838+ key ! ( supported_sanitizers, SanitizerSet ) ?;
17951839
17961840 // NB: The old name is deprecated, but support for it is retained for
17971841 // compatibility.
@@ -2029,6 +2073,7 @@ impl ToJson for Target {
20292073 target_option_val ! ( eh_frame_header) ;
20302074 target_option_val ! ( has_thumb_interworking) ;
20312075 target_option_val ! ( split_debuginfo) ;
2076+ target_option_val ! ( supported_sanitizers) ;
20322077
20332078 if default. unsupported_abis != self . unsupported_abis {
20342079 d. insert (
0 commit comments