Struct cwe_checker_lib::abstract_domain::IntervalDomain
source · pub struct IntervalDomain { /* private fields */ }
Expand description
An abstract domain representing values in an interval range with strides and widening hints.
The interval bounds are signed integers, i.e. the domain looses precision if tasked to represent large unsigned integers. The interval has a stride, i.e. all values represented by the interval are contained in the same residue class modulo the stride as the interval bounds.
The domain also contains widening hints to faciliate fast and exact widening for simple loop counter variables.
See the IntervalDomain::signed_merge_and_widen
method for details on the widening strategy.
Note that the widening hints may not respect the stride,
i.e. they may be contained in different residue classes than the interval bounds.
Implementations§
source§impl IntervalDomain
impl IntervalDomain
sourcepub fn add(&self, rhs: &Self) -> Self
pub fn add(&self, rhs: &Self) -> Self
Compute the interval of possible results
if one adds a value from self
to a value from rhs
.
sourcepub fn sub(&self, rhs: &Self) -> Self
pub fn sub(&self, rhs: &Self) -> Self
Compute the interval of possible results
if one subtracts a value in rhs
from a value in self
.
sourcepub fn signed_mul(&self, rhs: &Self) -> Self
pub fn signed_mul(&self, rhs: &Self) -> Self
Compute the interval of possible results
if one multiplies a value in self
with a value in rhs
.
sourcepub fn shift_left(&self, rhs: &Self) -> Self
pub fn shift_left(&self, rhs: &Self) -> Self
Compute the resulting interval after a left shift operation.
The result is only exact if the rhs
interval contains exactly one value.
source§impl IntervalDomain
impl IntervalDomain
sourcepub fn new(start: Bitvector, end: Bitvector) -> Self
pub fn new(start: Bitvector, end: Bitvector) -> Self
Create a new interval domain with the given bounds.
Both start
and end
are inclusive, i.e. contained in the interval.
The widening hints are set to None
and the stride is set to 1 if start != end
.
sourcepub fn equal_as_value_sets(&self, other: &IntervalDomain) -> bool
pub fn equal_as_value_sets(&self, other: &IntervalDomain) -> bool
Returns true if the two intervals represent the same value sets. This function ignores differences in the widening hints of the two intervals.
sourcepub fn update_widening_lower_bound(&mut self, bound: &Option<Bitvector>)
pub fn update_widening_lower_bound(&mut self, bound: &Option<Bitvector>)
If bound
is more exact/restrictive than the current lower bound of self
,
set the lower bound to bound
.
Otherwise keep the old lower bound.
sourcepub fn update_widening_upper_bound(&mut self, bound: &Option<Bitvector>)
pub fn update_widening_upper_bound(&mut self, bound: &Option<Bitvector>)
If bound
is more exact/restrictive than the current upper bound of self
,
set the upper bound to bound
.
Otherwise keep the old upper bound.
sourcepub fn signed_merge(&self, other: &IntervalDomain) -> IntervalDomain
pub fn signed_merge(&self, other: &IntervalDomain) -> IntervalDomain
Merge as signed intervals without performing widenings.
sourcepub fn signed_merge_and_widen(&self, other: &IntervalDomain) -> IntervalDomain
pub fn signed_merge_and_widen(&self, other: &IntervalDomain) -> IntervalDomain
Merge as signed intervals and perform widening if necessary.
Widening Strategy
The widening delay
Each interval has a widening_delay
counter,
which denotes the length of the interval after the last time that widening was performed.
For operations with more than one input,
the widening delay is set to the maximum of the input widening delays.
The only exception to this is the IntervalDomain::intersect()
method,
which may lower the value of the widening delay.
When to widen
If the merged interval equals one of the input intervals as value sets, do not perform widening. Else widening is performed if and only if the length of the interval is greater than the widening delay plus the stride of the interval.
How to widen
If no suitable widening bounds for widening exist, widen to the Top
value.
If exactly one widening bound exists, widen up to the bound,
but do not perform widening in the other direction of the interval.
If widening bounds for both directions exist, widen up to the bounds in both directions.
After that the widening_delay
is set to the length of the resulting interval.
sourcepub fn zero_extend(self, width: ByteSize) -> IntervalDomain
pub fn zero_extend(self, width: ByteSize) -> IntervalDomain
Zero-extend the values in the interval to the given width.
sourcepub fn sign_extend(self, width: ByteSize) -> Self
pub fn sign_extend(self, width: ByteSize) -> Self
Sign-extend the values in the interval to the given width.
sourcepub fn fits_into_size(&self, size: ByteSize) -> bool
pub fn fits_into_size(&self, size: ByteSize) -> bool
Check whether all values in the interval are representable by bitvectors of the given size
.
Does not check whether this is also true for the widening hints.
Trait Implementations§
source§impl AbstractDomain for IntervalDomain
impl AbstractDomain for IntervalDomain
source§fn merge(&self, other: &IntervalDomain) -> IntervalDomain
fn merge(&self, other: &IntervalDomain) -> IntervalDomain
Merge two interval domains and perform widening if necessary.
See IntervalDomain::signed_merge_and_widen
for the widening strategy.
source§impl Add for IntervalDomain
impl Add for IntervalDomain
source§impl Clone for IntervalDomain
impl Clone for IntervalDomain
source§fn clone(&self) -> IntervalDomain
fn clone(&self) -> IntervalDomain
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl Debug for IntervalDomain
impl Debug for IntervalDomain
source§impl<'de> Deserialize<'de> for IntervalDomain
impl<'de> Deserialize<'de> for IntervalDomain
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 Display for IntervalDomain
impl Display for IntervalDomain
source§impl From<ApInt> for IntervalDomain
impl From<ApInt> for IntervalDomain
source§impl From<Interval> for IntervalDomain
impl From<Interval> for IntervalDomain
source§fn from(interval: Interval) -> IntervalDomain
fn from(interval: Interval) -> IntervalDomain
Generate an interval domain without widening hints.
source§impl HasTop for IntervalDomain
impl HasTop for IntervalDomain
source§impl Hash for IntervalDomain
impl Hash for IntervalDomain
source§impl Neg for IntervalDomain
impl Neg for IntervalDomain
source§impl PartialEq for IntervalDomain
impl PartialEq for IntervalDomain
source§fn eq(&self, other: &IntervalDomain) -> bool
fn eq(&self, other: &IntervalDomain) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl RegisterDomain for IntervalDomain
impl RegisterDomain for IntervalDomain
source§fn bin_op(&self, op: BinOpType, rhs: &Self) -> Self
fn bin_op(&self, op: BinOpType, rhs: &Self) -> Self
Compute the result of a binary operation between two interval domains.
For binary operations that are not explicitly implemented the result is only exact if both intervals contain exactly one value.
source§fn un_op(&self, op: UnOpType) -> Self
fn un_op(&self, op: UnOpType) -> Self
Compute the result of an unary operation on the interval domain.
source§fn subpiece(&self, low_byte: ByteSize, size: ByteSize) -> Self
fn subpiece(&self, low_byte: ByteSize, size: ByteSize) -> Self
Take a sub-bitvector of the values in the interval domain.
source§fn cast(&self, kind: CastOpType, width: ByteSize) -> Self
fn cast(&self, kind: CastOpType, width: ByteSize) -> Self
Compute the result of a cast operation on the interval domain.
source§impl Serialize for IntervalDomain
impl Serialize for IntervalDomain
source§impl SizedDomain for IntervalDomain
impl SizedDomain for IntervalDomain
source§impl SpecializeByConditional for IntervalDomain
impl SpecializeByConditional for IntervalDomain
source§fn intersect(self, other: &Self) -> Result<Self, Error>
fn intersect(self, other: &Self) -> Result<Self, Error>
Compute the intersection of two intervals. Return an error if the intersection is empty.
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_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_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_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 Sub for IntervalDomain
impl Sub for IntervalDomain
source§impl TryToBitvec for IntervalDomain
impl TryToBitvec for IntervalDomain
source§impl TryToInterval for IntervalDomain
impl TryToInterval for IntervalDomain
source§fn try_to_interval(&self) -> Result<Interval, Error>
fn try_to_interval(&self) -> Result<Interval, Error>
If the domain represents a bounded (i.e. not Top
) interval, return it.
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 Eq for IntervalDomain
impl StructuralEq for IntervalDomain
impl StructuralPartialEq for IntervalDomain
Auto Trait Implementations§
impl RefUnwindSafe for IntervalDomain
impl Send for IntervalDomain
impl Sync for IntervalDomain
impl Unpin for IntervalDomain
impl UnwindSafe for IntervalDomain
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.