Struct cwe_checker_lib::abstract_domain::DataDomain
source · pub struct DataDomain<T: RegisterDomain> { /* private fields */ }
Expand description
An abstract domain representing a set of base values plus offsets or an absolute value (or both).
The base values are represented as abstract IDs,
i.e. they are treated as variables with unknown absolute value, e.g. the returned pointer by malloc.
For each base value the offset is given by an abstract domain T
,
which should specialize in representing absolute values (e.g. an interval domain).
Note that the domain assumes pointer semantics for these values.
That means if one applies operations to the domain that are not used in pointer arithmetics,
the abstract ID of the base value might be removed from the domain.
If the domain also represents absolute values,
then the values are given by a single instance of the abstract domain T
.
The domain also contains a flag to indicate that it includes Top
values,
i.e. values of fully unknown origin and offset.
Implementations§
source§impl<T: RegisterDomain> DataDomain<T>
impl<T: RegisterDomain> DataDomain<T>
sourcepub fn add_offset(&self, offset: &T) -> Self
pub fn add_offset(&self, offset: &T) -> Self
Add offset
to all contained absolute and relative values of self
and return the result.
sourcepub fn subtract_offset(&self, offset: &T) -> Self
pub fn subtract_offset(&self, offset: &T) -> Self
Subtract offset
from all contained absolute and relative values of self
and return the result.
source§impl<T: RegisterDomain> DataDomain<T>
impl<T: RegisterDomain> DataDomain<T>
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the domain does not represent any value.
The meaning of an empty value depends on the usage of the domain. E.g. it may indicate an impossible runtime state of a program in one analysis or simply no value of interest in another analysis.
An empty value represents the bottom value in the partial order of the domain.
sourcepub fn replace_abstract_id(
&mut self,
old_id: &AbstractIdentifier,
new_id: &AbstractIdentifier,
offset_adjustment: &T
)
pub fn replace_abstract_id( &mut self, old_id: &AbstractIdentifier, new_id: &AbstractIdentifier, offset_adjustment: &T )
For pointer values replace an abstract identifier with another one and add the offset_adjustment to the pointer offset. This is needed to adjust stack pointer on call and return instructions.
sourcepub fn replace_all_ids(
&mut self,
replacement_map: &BTreeMap<AbstractIdentifier, Self>
)
pub fn replace_all_ids( &mut self, replacement_map: &BTreeMap<AbstractIdentifier, Self> )
Replace all abstract IDs in self with the corresponding values given by the replacement_map
.
For IDs without a replacement value the contains_top_values
flag will be set.
sourcepub fn referenced_ids(&self) -> impl Iterator<Item = &AbstractIdentifier>
pub fn referenced_ids(&self) -> impl Iterator<Item = &AbstractIdentifier>
Return an iterator over all referenced abstract IDs.
sourcepub fn get_relative_values(&self) -> &BTreeMap<AbstractIdentifier, T>
pub fn get_relative_values(&self) -> &BTreeMap<AbstractIdentifier, T>
Return the relative values contained in the domain.
sourcepub fn set_relative_values(
&mut self,
relative_values: BTreeMap<AbstractIdentifier, T>
)
pub fn set_relative_values( &mut self, relative_values: BTreeMap<AbstractIdentifier, T> )
Replace the map of relative values with the given one.
sourcepub fn get_absolute_value(&self) -> Option<&T>
pub fn get_absolute_value(&self) -> Option<&T>
Return the absolute value contained in the domain if present
sourcepub fn set_absolute_value(&mut self, value: Option<T>)
pub fn set_absolute_value(&mut self, value: Option<T>)
Replace the absolute value contained in the domain with the given one.
A value of None
means that the domain does not contain an absolute value.
sourcepub fn contains_top(&self) -> bool
pub fn contains_top(&self) -> bool
Returns true
if the domain contains Top
values,
i.e. values for which neither a value nor an abstract identifier is known.
Note that the DataDomain
itself has no maximal value,
i.e. this does not indicate a Top
value of the abstract domain.
sourcepub fn set_contains_top_flag(&mut self)
pub fn set_contains_top_flag(&mut self)
Indicate that the domain may contain Top
values
in addition to the contained absolute and relative values.
This does not remove absolute or relative value information from the domain.
sourcepub fn unset_contains_top_flag(&mut self)
pub fn unset_contains_top_flag(&mut self)
Indicate that the domain does not contain any Top
values
in addition to the contained absolute and relative values.
sourcepub fn from_target(id: AbstractIdentifier, offset: T) -> Self
pub fn from_target(id: AbstractIdentifier, offset: T) -> Self
Return a new value representing a variable plus an offset, where the variable is represented by the given abstract ID.
sourcepub fn remove_ids(&mut self, ids_to_remove: &BTreeSet<AbstractIdentifier>)
pub fn remove_ids(&mut self, ids_to_remove: &BTreeSet<AbstractIdentifier>)
Remove all provided IDs from the list of relative values.
sourcepub fn get_if_absolute_value(&self) -> Option<&T>
pub fn get_if_absolute_value(&self) -> Option<&T>
Return the contained absolute value
only if self
contains no other (relative or Top
) values.
sourcepub fn get_if_unique_target(&self) -> Option<(&AbstractIdentifier, &T)>
pub fn get_if_unique_target(&self) -> Option<(&AbstractIdentifier, &T)>
Return the target ID and offset of the contained relative value
if self
contains exactly one relative value and no absolute or Top
values.
source§impl<T: RegisterDomain + Display> DataDomain<T>
impl<T: RegisterDomain + Display> DataDomain<T>
sourcepub fn to_json_compact(&self) -> Value
pub fn to_json_compact(&self) -> Value
Get a more compact json-representation of the data domain. Intended for pretty printing, not useable for serialization/deserialization.
Trait Implementations§
source§impl<T: RegisterDomain> AbstractDomain for DataDomain<T>
impl<T: RegisterDomain> AbstractDomain for DataDomain<T>
source§fn is_top(&self) -> bool
fn is_top(&self) -> bool
Return whether the element represents a top element or not.
Note that DataDomain
technically does not have a Top
element with respect to the partial order.
Instead a Top
element here represents a non-empty value
for which nothing is known about the contained values.
source§impl<T: RegisterDomain> Add for DataDomain<T>
impl<T: RegisterDomain> Add for DataDomain<T>
source§impl<T: Clone + RegisterDomain> Clone for DataDomain<T>
impl<T: Clone + RegisterDomain> Clone for DataDomain<T>
source§fn clone(&self) -> DataDomain<T>
fn clone(&self) -> DataDomain<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<T: Debug + RegisterDomain> Debug for DataDomain<T>
impl<T: Debug + RegisterDomain> Debug for DataDomain<T>
source§impl<'de, T> Deserialize<'de> for DataDomain<T>where
T: Deserialize<'de> + RegisterDomain,
impl<'de, T> Deserialize<'de> for DataDomain<T>where
T: Deserialize<'de> + RegisterDomain,
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
source§impl<T: RegisterDomain + From<Bitvector>> From<ApInt> for DataDomain<T>
impl<T: RegisterDomain + From<Bitvector>> From<ApInt> for DataDomain<T>
source§impl<T: RegisterDomain> From<T> for DataDomain<T>
impl<T: RegisterDomain> From<T> for DataDomain<T>
source§impl<T: RegisterDomain> HasTop for DataDomain<T>
impl<T: RegisterDomain> HasTop for DataDomain<T>
source§impl<'a> HasVsaResult<DataDomain<IntervalDomain>> for Context<'a>
impl<'a> HasVsaResult<DataDomain<IntervalDomain>> for Context<'a>
source§fn vsa_result(&self) -> &impl VsaResult<ValueDomain = PiData>
fn vsa_result(&self) -> &impl VsaResult<ValueDomain = PiData>
Self
into a reference to a type that implements
VsaResult
with ValueDomain
T
.source§impl<T: Hash + RegisterDomain> Hash for DataDomain<T>
impl<T: Hash + RegisterDomain> Hash for DataDomain<T>
source§impl<T: PartialEq + RegisterDomain> PartialEq for DataDomain<T>
impl<T: PartialEq + RegisterDomain> PartialEq for DataDomain<T>
source§fn eq(&self, other: &DataDomain<T>) -> bool
fn eq(&self, other: &DataDomain<T>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<T: RegisterDomain> RegisterDomain for DataDomain<T>
impl<T: RegisterDomain> RegisterDomain for DataDomain<T>
source§impl<T> Serialize for DataDomain<T>where
T: Serialize + RegisterDomain,
impl<T> Serialize for DataDomain<T>where
T: Serialize + RegisterDomain,
source§impl<T: RegisterDomain> SizedDomain for DataDomain<T>
impl<T: RegisterDomain> SizedDomain for DataDomain<T>
source§fn new_top(bytesize: ByteSize) -> Self
fn new_top(bytesize: ByteSize) -> Self
Return a new Top element with the given bytesize.
Note that DataDomain
technically does not have a Top
element with respect to the partial order.
Instead a Top
element here represents a non-empty value
for which nothing is known about the contained values.
source§impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for DataDomain<T>
impl<T: SpecializeByConditional + RegisterDomain> SpecializeByConditional for DataDomain<T>
source§fn intersect(self, other: &Self) -> Result<Self, Error>
fn intersect(self, other: &Self) -> Result<Self, Error>
Compute the intersetion of two DataDomains.
Note that this implementation is unsound for several reasons:
- For example, it assumes that two different relative values cannot intersect. But that is not true if their offfsets are big enough or if the relative values do in fact reference the same object despite having different identifiers.
- If intersecting relative values with absolute values we represent the result with the absolute values. But depending on the use-case an approximation by the relative values could be more precise.
source§fn add_signed_less_equal_bound(self, bound: &Bitvector) -> Result<Self, Error>
fn add_signed_less_equal_bound(self, bound: &Bitvector) -> Result<Self, Error>
self
to values satisfying self <= bound
with self
and bound
interpreted as signed integers.
Returns an error if no value represented by self
can satisfy the comparison.source§fn add_unsigned_less_equal_bound(self, bound: &Bitvector) -> Result<Self, Error>
fn add_unsigned_less_equal_bound(self, bound: &Bitvector) -> Result<Self, Error>
self
to values satisfying self <= bound
with self
and bound
interpreted as unsigned integers.
Returns an error if no value represented by self
can satisfy the comparison.source§fn add_signed_greater_equal_bound(
self,
bound: &Bitvector
) -> Result<Self, Error>
fn add_signed_greater_equal_bound( self, bound: &Bitvector ) -> Result<Self, Error>
self
to values satisfying self >= bound
with self
and bound
interpreted as signed integers.
Returns an error if no value represented by self
can satisfy the comparison.source§fn add_unsigned_greater_equal_bound(
self,
bound: &Bitvector
) -> Result<Self, Error>
fn add_unsigned_greater_equal_bound( self, bound: &Bitvector ) -> Result<Self, Error>
self
to values satisfying self >= bound
with self
and bound
interpreted as unsigned integers.
Returns an error if no value represented by self
can satisfy the comparison.source§fn add_not_equal_bound(self, bound: &Bitvector) -> Result<Self, Error>
fn add_not_equal_bound(self, bound: &Bitvector) -> Result<Self, Error>
self
to values satisfying self != bound
Returns an error if self
only represents one value for which self == bound
holds.source§fn without_widening_hints(self) -> Self
fn without_widening_hints(self) -> Self
self
.
Necessary for cases where several sources have widening hints,
but only one source should contribute widening hints to the result.source§impl<T: RegisterDomain> Sub for DataDomain<T>
impl<T: RegisterDomain> Sub for DataDomain<T>
source§impl<T: RegisterDomain + TryToBitvec> TryToBitvec for DataDomain<T>
impl<T: RegisterDomain + TryToBitvec> TryToBitvec for DataDomain<T>
source§impl<T: RegisterDomain + TryToInterval> TryToInterval for DataDomain<T>
impl<T: RegisterDomain + TryToInterval> TryToInterval for DataDomain<T>
source§fn try_to_interval(&self) -> Result<Interval, Error>
fn try_to_interval(&self) -> Result<Interval, Error>
If the domain represents (or can be widened to) an interval of absolute values, return the interval.
source§fn try_to_offset_interval(&self) -> Result<(i64, i64), Error>
fn try_to_offset_interval(&self) -> Result<(i64, i64), Error>
self
represents an interval of absolute values (or can be widened to represent such an interval)
then return it as an interval of signed integers of the form (start, end)
if the interval is bounded.
Else return an error.
Note that the conversion loses information about the bytesize of the values contained in the interval.impl<T: Eq + RegisterDomain> Eq for DataDomain<T>
impl<T: RegisterDomain> StructuralEq for DataDomain<T>
impl<T: RegisterDomain> StructuralPartialEq for DataDomain<T>
Auto Trait Implementations§
impl<T> RefUnwindSafe for DataDomain<T>where
T: RefUnwindSafe,
impl<T> Send for DataDomain<T>where
T: Send,
impl<T> Sync for DataDomain<T>where
T: Sync,
impl<T> Unpin for DataDomain<T>where
T: Unpin,
impl<T> UnwindSafe for DataDomain<T>where
T: UnwindSafe + RefUnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.