@@ -600,19 +600,28 @@ bitflags::bitflags! {
600
600
}
601
601
}
602
602
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
+
603
619
/// Formats a sanitizer set as a comma separated list of sanitizers' names.
604
620
impl fmt:: Display for SanitizerSet {
605
621
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
606
622
let mut first = true ;
607
623
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) ) ;
616
625
if !first {
617
626
f. write_str ( ", " ) ?;
618
627
}
@@ -628,12 +637,18 @@ impl IntoIterator for SanitizerSet {
628
637
type IntoIter = std:: vec:: IntoIter < SanitizerSet > ;
629
638
630
639
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 ( )
637
652
}
638
653
}
639
654
@@ -643,6 +658,16 @@ impl<CTX> HashStable<CTX> for SanitizerSet {
643
658
}
644
659
}
645
660
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
+
646
671
macro_rules! supported_targets {
647
672
( $( ( $( $triple: literal, ) + $module: ident ) , ) + ) => {
648
673
$( mod $module; ) +
@@ -1614,6 +1639,24 @@ impl Target {
1614
1639
) ) ,
1615
1640
} ) . unwrap_or( Ok ( ( ) ) )
1616
1641
} ) ;
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
+
1617
1660
( $key_name: ident, crt_objects_fallback) => ( {
1618
1661
let name = ( stringify!( $key_name) ) . replace( "_" , "-" ) ;
1619
1662
obj. find( & name[ ..] ) . and_then( |o| o. as_string( ) . and_then( |s| {
@@ -1792,6 +1835,7 @@ impl Target {
1792
1835
key ! ( eh_frame_header, bool ) ;
1793
1836
key ! ( has_thumb_interworking, bool ) ;
1794
1837
key ! ( split_debuginfo, SplitDebuginfo ) ?;
1838
+ key ! ( supported_sanitizers, SanitizerSet ) ?;
1795
1839
1796
1840
// NB: The old name is deprecated, but support for it is retained for
1797
1841
// compatibility.
@@ -2029,6 +2073,7 @@ impl ToJson for Target {
2029
2073
target_option_val ! ( eh_frame_header) ;
2030
2074
target_option_val ! ( has_thumb_interworking) ;
2031
2075
target_option_val ! ( split_debuginfo) ;
2076
+ target_option_val ! ( supported_sanitizers) ;
2032
2077
2033
2078
if default. unsupported_abis != self . unsupported_abis {
2034
2079
d. insert (
0 commit comments