Skip to main content

rustc_structures/
sanitizer_set.rs

1use core::fmt;
2use std::str::FromStr;
3
4#[cfg(feature = "nightly")]
5use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash};
6
7#[derive(#[automatically_derived]
impl ::core::default::Default for SanitizerSet {
    #[inline]
    fn default() -> SanitizerSet {
        SanitizerSet(::core::default::Default::default())
    }
}Default, #[automatically_derived]
impl ::core::clone::Clone for SanitizerSet {
    #[inline]
    fn clone(&self) -> SanitizerSet {
        let _: ::core::clone::AssertParamIsClone<u16>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SanitizerSet { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for SanitizerSet {
    #[inline]
    fn eq(&self, other: &SanitizerSet) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SanitizerSet {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u16>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for SanitizerSet {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash)]
8#[cfg_attr(feature = "nightly", derive(const _: () =
    {
        impl<__E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for SanitizerSet {
            fn encode(&self, __encoder: &mut __E) {
                let SanitizerSet(ref __binding_0) = *self;
                ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                    __encoder);
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<__D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for SanitizerSet {
            fn decode(__decoder: &mut __D) -> Self {
                SanitizerSet(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };Decodable_NoContext, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for SanitizerSet
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    SanitizerSet(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash))]
9pub struct SanitizerSet(u16);
10impl SanitizerSet {
    #[allow(deprecated, non_upper_case_globals,)]
    pub const ADDRESS: Self = Self::from_bits_retain(1 << 0);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const LEAK: Self = Self::from_bits_retain(1 << 1);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const MEMORY: Self = Self::from_bits_retain(1 << 2);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const THREAD: Self = Self::from_bits_retain(1 << 3);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const HWADDRESS: Self = Self::from_bits_retain(1 << 4);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const CFI: Self = Self::from_bits_retain(1 << 5);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const MEMTAG: Self = Self::from_bits_retain(1 << 6);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const SHADOWCALLSTACK: Self = Self::from_bits_retain(1 << 7);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const KCFI: Self = Self::from_bits_retain(1 << 8);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const KERNELADDRESS: Self = Self::from_bits_retain(1 << 9);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const KERNELHWADDRESS: Self = Self::from_bits_retain(1 << 10);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const SAFESTACK: Self = Self::from_bits_retain(1 << 11);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const DATAFLOW: Self = Self::from_bits_retain(1 << 12);
    #[allow(deprecated, non_upper_case_globals,)]
    pub const REALTIME: Self = Self::from_bits_retain(1 << 13);
}
impl ::bitflags::Flags for SanitizerSet {
    const FLAGS: &'static [::bitflags::Flag<SanitizerSet>] =
        &[{

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("ADDRESS", SanitizerSet::ADDRESS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("LEAK", SanitizerSet::LEAK)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("MEMORY", SanitizerSet::MEMORY)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("THREAD", SanitizerSet::THREAD)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("HWADDRESS", SanitizerSet::HWADDRESS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("CFI", SanitizerSet::CFI)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("MEMTAG", SanitizerSet::MEMTAG)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("SHADOWCALLSTACK",
                            SanitizerSet::SHADOWCALLSTACK)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("KCFI", SanitizerSet::KCFI)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("KERNELADDRESS",
                            SanitizerSet::KERNELADDRESS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("KERNELHWADDRESS",
                            SanitizerSet::KERNELHWADDRESS)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("SAFESTACK", SanitizerSet::SAFESTACK)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("DATAFLOW", SanitizerSet::DATAFLOW)
                    },
                    {

                        #[allow(deprecated, non_upper_case_globals,)]
                        ::bitflags::Flag::new("REALTIME", SanitizerSet::REALTIME)
                    }];
    type Bits = u16;
    fn bits(&self) -> u16 { SanitizerSet::bits(self) }
    fn from_bits_retain(bits: u16) -> SanitizerSet {
        SanitizerSet::from_bits_retain(bits)
    }
}
#[allow(dead_code, deprecated, unused_doc_comments, unused_attributes,
unused_mut, unused_imports, non_upper_case_globals, clippy ::
assign_op_pattern, clippy :: iter_without_into_iter,)]
const _: () =
    {
        #[allow(dead_code, deprecated, unused_attributes)]
        impl SanitizerSet {
            /// Get a flags value with all bits unset.
            #[inline]
            pub const fn empty() -> Self {
                Self(<u16 as ::bitflags::Bits>::EMPTY)
            }
            /// Get a flags value with all known bits set.
            #[inline]
            pub const fn all() -> Self {
                let mut truncated = <u16 as ::bitflags::Bits>::EMPTY;
                let mut i = 0;
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                {
                    {
                        let flag =
                            <SanitizerSet as
                                            ::bitflags::Flags>::FLAGS[i].value().bits();
                        truncated = truncated | flag;
                        i += 1;
                    }
                };
                let _ = i;
                Self(truncated)
            }
            /// Get the underlying bits value.
            ///
            /// The returned value is exactly the bits set in this flags value.
            #[inline]
            pub const fn bits(&self) -> u16 { self.0 }
            /// Convert from a bits value.
            ///
            /// This method will return `None` if any unknown bits are set.
            #[inline]
            pub const fn from_bits(bits: u16)
                -> ::bitflags::__private::core::option::Option<Self> {
                let truncated = Self::from_bits_truncate(bits).0;
                if truncated == bits {
                    ::bitflags::__private::core::option::Option::Some(Self(bits))
                } else { ::bitflags::__private::core::option::Option::None }
            }
            /// Convert from a bits value, unsetting any unknown bits.
            #[inline]
            pub const fn from_bits_truncate(bits: u16) -> Self {
                Self(bits & Self::all().0)
            }
            /// Convert from a bits value exactly.
            #[inline]
            pub const fn from_bits_retain(bits: u16) -> Self { Self(bits) }
            /// Get a flags value with the bits of a flag with the given name set.
            ///
            /// This method will return `None` if `name` is empty or doesn't
            /// correspond to any named flag.
            #[inline]
            pub fn from_name(name: &str)
                -> ::bitflags::__private::core::option::Option<Self> {
                {
                    if name == "ADDRESS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::ADDRESS.bits()));
                    }
                };
                ;
                {
                    if name == "LEAK" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::LEAK.bits()));
                    }
                };
                ;
                {
                    if name == "MEMORY" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::MEMORY.bits()));
                    }
                };
                ;
                {
                    if name == "THREAD" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::THREAD.bits()));
                    }
                };
                ;
                {
                    if name == "HWADDRESS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::HWADDRESS.bits()));
                    }
                };
                ;
                {
                    if name == "CFI" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::CFI.bits()));
                    }
                };
                ;
                {
                    if name == "MEMTAG" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::MEMTAG.bits()));
                    }
                };
                ;
                {
                    if name == "SHADOWCALLSTACK" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::SHADOWCALLSTACK.bits()));
                    }
                };
                ;
                {
                    if name == "KCFI" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::KCFI.bits()));
                    }
                };
                ;
                {
                    if name == "KERNELADDRESS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::KERNELADDRESS.bits()));
                    }
                };
                ;
                {
                    if name == "KERNELHWADDRESS" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::KERNELHWADDRESS.bits()));
                    }
                };
                ;
                {
                    if name == "SAFESTACK" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::SAFESTACK.bits()));
                    }
                };
                ;
                {
                    if name == "DATAFLOW" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::DATAFLOW.bits()));
                    }
                };
                ;
                {
                    if name == "REALTIME" {
                        return ::bitflags::__private::core::option::Option::Some(Self(SanitizerSet::REALTIME.bits()));
                    }
                };
                ;
                let _ = name;
                ::bitflags::__private::core::option::Option::None
            }
            /// Whether all bits in this flags value are unset.
            #[inline]
            pub const fn is_empty(&self) -> bool {
                self.0 == <u16 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all known bits in this flags value are set.
            #[inline]
            pub const fn is_all(&self) -> bool {
                Self::all().0 | self.0 == self.0
            }
            /// Whether any set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn intersects(&self, other: Self) -> bool {
                self.0 & other.0 != <u16 as ::bitflags::Bits>::EMPTY
            }
            /// Whether all set bits in a source flags value are also set in a target flags value.
            #[inline]
            pub const fn contains(&self, other: Self) -> bool {
                self.0 & other.0 == other.0
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            pub fn insert(&mut self, other: Self) {
                *self = Self(self.0).union(other);
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `remove` won't truncate `other`, but the `!` operator will.
            #[inline]
            pub fn remove(&mut self, other: Self) {
                *self = Self(self.0).difference(other);
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            pub fn toggle(&mut self, other: Self) {
                *self = Self(self.0).symmetric_difference(other);
            }
            /// Call `insert` when `value` is `true` or `remove` when `value` is `false`.
            #[inline]
            pub fn set(&mut self, other: Self, value: bool) {
                if value { self.insert(other); } else { self.remove(other); }
            }
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn intersection(self, other: Self) -> Self {
                Self(self.0 & other.0)
            }
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn union(self, other: Self) -> Self {
                Self(self.0 | other.0)
            }
            /// The intersection of a source flags value with the complement of a target flags
            /// value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            #[must_use]
            pub const fn difference(self, other: Self) -> Self {
                Self(self.0 & !other.0)
            }
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            #[must_use]
            pub const fn symmetric_difference(self, other: Self) -> Self {
                Self(self.0 ^ other.0)
            }
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            #[must_use]
            pub const fn complement(self) -> Self {
                Self::from_bits_truncate(!self.0)
            }
        }
        impl ::bitflags::__private::core::fmt::Binary for SanitizerSet {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Binary::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::Octal for SanitizerSet {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::Octal::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::LowerHex for SanitizerSet {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::LowerHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::fmt::UpperHex for SanitizerSet {
            fn fmt(&self, f: &mut ::bitflags::__private::core::fmt::Formatter)
                -> ::bitflags::__private::core::fmt::Result {
                let inner = self.0;
                ::bitflags::__private::core::fmt::UpperHex::fmt(&inner, f)
            }
        }
        impl ::bitflags::__private::core::ops::BitOr for SanitizerSet {
            type Output = Self;
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor(self, other: SanitizerSet) -> Self { self.union(other) }
        }
        impl ::bitflags::__private::core::ops::BitOrAssign for SanitizerSet {
            /// The bitwise or (`|`) of the bits in two flags values.
            #[inline]
            fn bitor_assign(&mut self, other: Self) { self.insert(other); }
        }
        impl ::bitflags::__private::core::ops::BitXor for SanitizerSet {
            type Output = Self;
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor(self, other: Self) -> Self {
                self.symmetric_difference(other)
            }
        }
        impl ::bitflags::__private::core::ops::BitXorAssign for SanitizerSet {
            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
            #[inline]
            fn bitxor_assign(&mut self, other: Self) { self.toggle(other); }
        }
        impl ::bitflags::__private::core::ops::BitAnd for SanitizerSet {
            type Output = Self;
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand(self, other: Self) -> Self { self.intersection(other) }
        }
        impl ::bitflags::__private::core::ops::BitAndAssign for SanitizerSet {
            /// The bitwise and (`&`) of the bits in two flags values.
            #[inline]
            fn bitand_assign(&mut self, other: Self) {
                *self =
                    Self::from_bits_retain(self.bits()).intersection(other);
            }
        }
        impl ::bitflags::__private::core::ops::Sub for SanitizerSet {
            type Output = Self;
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub(self, other: Self) -> Self { self.difference(other) }
        }
        impl ::bitflags::__private::core::ops::SubAssign for SanitizerSet {
            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
            ///
            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
            /// `difference` won't truncate `other`, but the `!` operator will.
            #[inline]
            fn sub_assign(&mut self, other: Self) { self.remove(other); }
        }
        impl ::bitflags::__private::core::ops::Not for SanitizerSet {
            type Output = Self;
            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
            #[inline]
            fn not(self) -> Self { self.complement() }
        }
        impl ::bitflags::__private::core::iter::Extend<SanitizerSet> for
            SanitizerSet {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn extend<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(&mut self, iterator: T) {
                for item in iterator { self.insert(item) }
            }
        }
        impl ::bitflags::__private::core::iter::FromIterator<SanitizerSet> for
            SanitizerSet {
            /// The bitwise or (`|`) of the bits in each flags value.
            fn from_iter<T: ::bitflags::__private::core::iter::IntoIterator<Item
                = Self>>(iterator: T) -> Self {
                use ::bitflags::__private::core::iter::Extend;
                let mut result = Self::empty();
                result.extend(iterator);
                result
            }
        }
        impl SanitizerSet {
            /// Yield a set of contained flags values.
            ///
            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
            /// will be yielded together as a final flags value.
            #[inline]
            pub const fn iter(&self) -> ::bitflags::iter::Iter<SanitizerSet> {
                ::bitflags::iter::Iter::__private_const_new(<SanitizerSet as
                        ::bitflags::Flags>::FLAGS,
                    SanitizerSet::from_bits_retain(self.bits()),
                    SanitizerSet::from_bits_retain(self.bits()))
            }
            /// Yield a set of contained named flags values.
            ///
            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
            #[inline]
            pub const fn iter_names(&self)
                -> ::bitflags::iter::IterNames<SanitizerSet> {
                ::bitflags::iter::IterNames::__private_const_new(<SanitizerSet
                        as ::bitflags::Flags>::FLAGS,
                    SanitizerSet::from_bits_retain(self.bits()),
                    SanitizerSet::from_bits_retain(self.bits()))
            }
        }
        impl ::bitflags::__private::core::iter::IntoIterator for SanitizerSet
            {
            type Item = SanitizerSet;
            type IntoIter = ::bitflags::iter::Iter<SanitizerSet>;
            fn into_iter(self) -> Self::IntoIter { self.iter() }
        }
    };bitflags::bitflags! {
11    impl SanitizerSet: u16 {
12        const ADDRESS = 1 << 0;
13        const LEAK    = 1 << 1;
14        const MEMORY  = 1 << 2;
15        const THREAD  = 1 << 3;
16        const HWADDRESS = 1 << 4;
17        const CFI     = 1 << 5;
18        const MEMTAG  = 1 << 6;
19        const SHADOWCALLSTACK = 1 << 7;
20        const KCFI    = 1 << 8;
21        const KERNELADDRESS = 1 << 9;
22        const KERNELHWADDRESS = 1 << 10;
23        const SAFESTACK = 1 << 11;
24        const DATAFLOW = 1 << 12;
25        const REALTIME = 1 << 13;
26    }
27}
28
29#[cfg(feature = "nightly")]
30impl ::std::fmt::Debug for SanitizerSet {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        ::bitflags::parser::to_writer(self, f)
    }
}rustc_data_structures::external_bitflags_debug! { SanitizerSet }
31
32impl SanitizerSet {
33    // Taken from LLVM's sanitizer compatibility logic:
34    // https://github.com/llvm/llvm-project/blob/release/18.x/clang/lib/Driver/SanitizerArgs.cpp#L512
35    const MUTUALLY_EXCLUSIVE: &'static [(SanitizerSet, SanitizerSet)] = &[
36        (SanitizerSet::ADDRESS, SanitizerSet::MEMORY),
37        (SanitizerSet::ADDRESS, SanitizerSet::THREAD),
38        (SanitizerSet::ADDRESS, SanitizerSet::HWADDRESS),
39        (SanitizerSet::ADDRESS, SanitizerSet::MEMTAG),
40        (SanitizerSet::ADDRESS, SanitizerSet::KERNELADDRESS),
41        (SanitizerSet::ADDRESS, SanitizerSet::KERNELHWADDRESS),
42        (SanitizerSet::ADDRESS, SanitizerSet::SAFESTACK),
43        (SanitizerSet::LEAK, SanitizerSet::MEMORY),
44        (SanitizerSet::LEAK, SanitizerSet::THREAD),
45        (SanitizerSet::LEAK, SanitizerSet::KERNELADDRESS),
46        (SanitizerSet::LEAK, SanitizerSet::KERNELHWADDRESS),
47        (SanitizerSet::LEAK, SanitizerSet::SAFESTACK),
48        (SanitizerSet::MEMORY, SanitizerSet::THREAD),
49        (SanitizerSet::MEMORY, SanitizerSet::HWADDRESS),
50        (SanitizerSet::MEMORY, SanitizerSet::KERNELADDRESS),
51        (SanitizerSet::MEMORY, SanitizerSet::KERNELHWADDRESS),
52        (SanitizerSet::MEMORY, SanitizerSet::SAFESTACK),
53        (SanitizerSet::THREAD, SanitizerSet::HWADDRESS),
54        (SanitizerSet::THREAD, SanitizerSet::KERNELADDRESS),
55        (SanitizerSet::THREAD, SanitizerSet::KERNELHWADDRESS),
56        (SanitizerSet::THREAD, SanitizerSet::SAFESTACK),
57        (SanitizerSet::HWADDRESS, SanitizerSet::MEMTAG),
58        (SanitizerSet::HWADDRESS, SanitizerSet::KERNELADDRESS),
59        (SanitizerSet::HWADDRESS, SanitizerSet::KERNELHWADDRESS),
60        (SanitizerSet::HWADDRESS, SanitizerSet::SAFESTACK),
61        (SanitizerSet::CFI, SanitizerSet::KCFI),
62        (SanitizerSet::MEMTAG, SanitizerSet::KERNELADDRESS),
63        (SanitizerSet::MEMTAG, SanitizerSet::KERNELHWADDRESS),
64        (SanitizerSet::KERNELADDRESS, SanitizerSet::KERNELHWADDRESS),
65        (SanitizerSet::KERNELADDRESS, SanitizerSet::SAFESTACK),
66        (SanitizerSet::KERNELHWADDRESS, SanitizerSet::SAFESTACK),
67    ];
68
69    /// Return sanitizer's name
70    ///
71    /// Returns none if the flags is a set of sanitizers numbering not exactly one.
72    pub fn as_str(self) -> Option<&'static str> {
73        Some(match self {
74            SanitizerSet::ADDRESS => "address",
75            SanitizerSet::CFI => "cfi",
76            SanitizerSet::DATAFLOW => "dataflow",
77            SanitizerSet::KCFI => "kcfi",
78            SanitizerSet::KERNELADDRESS => "kernel-address",
79            SanitizerSet::KERNELHWADDRESS => "kernel-hwaddress",
80            SanitizerSet::LEAK => "leak",
81            SanitizerSet::MEMORY => "memory",
82            SanitizerSet::MEMTAG => "memtag",
83            SanitizerSet::SAFESTACK => "safestack",
84            SanitizerSet::SHADOWCALLSTACK => "shadow-call-stack",
85            SanitizerSet::THREAD => "thread",
86            SanitizerSet::HWADDRESS => "hwaddress",
87            SanitizerSet::REALTIME => "realtime",
88            _ => return None,
89        })
90    }
91
92    pub fn mutually_exclusive(self) -> Option<(SanitizerSet, SanitizerSet)> {
93        Self::MUTUALLY_EXCLUSIVE
94            .into_iter()
95            .find(|&(a, b)| self.contains(*a) && self.contains(*b))
96            .copied()
97    }
98}
99
100/// Formats a sanitizer set as a comma separated list of sanitizers' names.
101impl fmt::Display for SanitizerSet {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        let mut first = true;
104        for s in *self {
105            let name = s.as_str().unwrap_or_else(|| {
    ::core::panicking::panic_fmt(format_args!("unrecognized sanitizer {0:?}",
            s));
}panic!("unrecognized sanitizer {s:?}"));
106            if !first {
107                f.write_str(", ")?;
108            }
109            f.write_str(name)?;
110            first = false;
111        }
112        Ok(())
113    }
114}
115
116impl FromStr for SanitizerSet {
117    type Err = String;
118    fn from_str(s: &str) -> Result<Self, Self::Err> {
119        Ok(match s {
120            "address" => SanitizerSet::ADDRESS,
121            "cfi" => SanitizerSet::CFI,
122            "dataflow" => SanitizerSet::DATAFLOW,
123            "kcfi" => SanitizerSet::KCFI,
124            "kernel-address" => SanitizerSet::KERNELADDRESS,
125            "kernel-hwaddress" => SanitizerSet::KERNELHWADDRESS,
126            "leak" => SanitizerSet::LEAK,
127            "memory" => SanitizerSet::MEMORY,
128            "memtag" => SanitizerSet::MEMTAG,
129            "safestack" => SanitizerSet::SAFESTACK,
130            "shadow-call-stack" => SanitizerSet::SHADOWCALLSTACK,
131            "thread" => SanitizerSet::THREAD,
132            "hwaddress" => SanitizerSet::HWADDRESS,
133            "realtime" => SanitizerSet::REALTIME,
134            s => return Err(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown sanitizer {0}", s))
    })format!("unknown sanitizer {s}")),
135        })
136    }
137}
138
139impl schemars::JsonSchema for SanitizerSet {
140    fn schema_name() -> std::borrow::Cow<'static, str> {
141        "SanitizerSet".into()
142    }
143    fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
144        let all = Self::all().iter().map(|sanitizer| sanitizer.as_str()).collect::<Vec<_>>();
145        <::schemars::Schema as
            ::core::convert::TryFrom<_>>::try_from(::serde_json::Value::Object({
                let mut object = ::serde_json::Map::new();
                let _ =
                    object.insert(("type").into(),
                        ::serde_json::to_value(&"string").unwrap());
                let _ =
                    object.insert(("enum").into(),
                        ::serde_json::to_value(&all).unwrap());
                ;
                object
            })).unwrap()schemars::json_schema! ({
146            "type": "string",
147            "enum": all,
148        })
149    }
150}
151
152impl<'de> serde::Deserialize<'de> for SanitizerSet {
153    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
154    where
155        D: serde::Deserializer<'de>,
156    {
157        let s = String::deserialize(deserializer)?;
158        FromStr::from_str(&s).map_err(serde::de::Error::custom)
159    }
160}