Make HasTop and HasBottom consts.
This commit is contained in:
parent
f7b831ac8a
commit
71138e9933
@ -75,12 +75,12 @@ pub trait MeetSemiLattice: Eq {
|
||||
|
||||
/// A set that has a "bottom" element, which is less than or equal to any other element.
|
||||
pub trait HasBottom {
|
||||
fn bottom() -> Self;
|
||||
const BOTTOM: Self;
|
||||
}
|
||||
|
||||
/// A set that has a "top" element, which is greater than or equal to any other element.
|
||||
pub trait HasTop {
|
||||
fn top() -> Self;
|
||||
const TOP: Self;
|
||||
}
|
||||
|
||||
/// A `bool` is a "two-point" lattice with `true` as the top element and `false` as the bottom:
|
||||
@ -113,15 +113,11 @@ fn meet(&mut self, other: &Self) -> bool {
|
||||
}
|
||||
|
||||
impl HasBottom for bool {
|
||||
fn bottom() -> Self {
|
||||
false
|
||||
}
|
||||
const BOTTOM: Self = false;
|
||||
}
|
||||
|
||||
impl HasTop for bool {
|
||||
fn top() -> Self {
|
||||
true
|
||||
}
|
||||
const TOP: Self = true;
|
||||
}
|
||||
|
||||
/// A tuple (or list) of lattices is itself a lattice whose least upper bound is the concatenation
|
||||
@ -274,13 +270,9 @@ fn meet(&mut self, other: &Self) -> bool {
|
||||
}
|
||||
|
||||
impl<T> HasBottom for FlatSet<T> {
|
||||
fn bottom() -> Self {
|
||||
Self::Bottom
|
||||
}
|
||||
const BOTTOM: Self = Self::Bottom;
|
||||
}
|
||||
|
||||
impl<T> HasTop for FlatSet<T> {
|
||||
fn top() -> Self {
|
||||
Self::Top
|
||||
}
|
||||
const TOP: Self = Self::Top;
|
||||
}
|
||||
|
@ -74,11 +74,11 @@ fn super_statement(&self, statement: &Statement<'tcx>, state: &mut State<Self::V
|
||||
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
|
||||
// StorageLive leaves the local in an uninitialized state.
|
||||
// StorageDead makes it UB to access the local afterwards.
|
||||
state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::bottom());
|
||||
state.flood_with(Place::from(*local).as_ref(), self.map(), Self::Value::BOTTOM);
|
||||
}
|
||||
StatementKind::Deinit(box place) => {
|
||||
// Deinit makes the place uninitialized.
|
||||
state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
|
||||
state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM);
|
||||
}
|
||||
StatementKind::Retag(..) => {
|
||||
// We don't track references.
|
||||
@ -154,7 +154,7 @@ fn super_rvalue(
|
||||
Rvalue::CopyForDeref(place) => self.handle_operand(&Operand::Copy(*place), state),
|
||||
Rvalue::Ref(..) | Rvalue::AddressOf(..) => {
|
||||
// We don't track such places.
|
||||
ValueOrPlace::top()
|
||||
ValueOrPlace::TOP
|
||||
}
|
||||
Rvalue::Repeat(..)
|
||||
| Rvalue::ThreadLocalRef(..)
|
||||
@ -168,7 +168,7 @@ fn super_rvalue(
|
||||
| Rvalue::Aggregate(..)
|
||||
| Rvalue::ShallowInitBox(..) => {
|
||||
// No modification is possible through these r-values.
|
||||
ValueOrPlace::top()
|
||||
ValueOrPlace::TOP
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,7 +196,7 @@ fn super_operand(
|
||||
self.map()
|
||||
.find(place.as_ref())
|
||||
.map(ValueOrPlace::Place)
|
||||
.unwrap_or(ValueOrPlace::top())
|
||||
.unwrap_or(ValueOrPlace::TOP)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,7 +214,7 @@ fn super_constant(
|
||||
_constant: &Constant<'tcx>,
|
||||
_state: &mut State<Self::Value>,
|
||||
) -> Self::Value {
|
||||
Self::Value::top()
|
||||
Self::Value::TOP
|
||||
}
|
||||
|
||||
/// The effect of a successful function call return should not be
|
||||
@ -229,7 +229,7 @@ fn super_terminator(&self, terminator: &Terminator<'tcx>, state: &mut State<Self
|
||||
// Effect is applied by `handle_call_return`.
|
||||
}
|
||||
TerminatorKind::Drop { place, .. } => {
|
||||
state.flood_with(place.as_ref(), self.map(), Self::Value::bottom());
|
||||
state.flood_with(place.as_ref(), self.map(), Self::Value::BOTTOM);
|
||||
}
|
||||
TerminatorKind::Yield { .. } => {
|
||||
// They would have an effect, but are not allowed in this phase.
|
||||
@ -307,7 +307,7 @@ fn bottom_value(&self, _body: &Body<'tcx>) -> Self::Domain {
|
||||
fn initialize_start_block(&self, body: &Body<'tcx>, state: &mut Self::Domain) {
|
||||
// The initial state maps all tracked places of argument projections to ⊤ and the rest to ⊥.
|
||||
assert!(matches!(state.0, StateData::Unreachable));
|
||||
let values = IndexVec::from_elem_n(T::Value::bottom(), self.0.map().value_count);
|
||||
let values = IndexVec::from_elem_n(T::Value::BOTTOM, self.0.map().value_count);
|
||||
*state = State(StateData::Reachable(values));
|
||||
for arg in body.args_iter() {
|
||||
state.flood(PlaceRef { local: arg, projection: &[] }, self.0.map());
|
||||
@ -437,7 +437,7 @@ pub fn mark_unreachable(&mut self) {
|
||||
}
|
||||
|
||||
pub fn flood_all(&mut self) {
|
||||
self.flood_all_with(V::top())
|
||||
self.flood_all_with(V::TOP)
|
||||
}
|
||||
|
||||
pub fn flood_all_with(&mut self, value: V) {
|
||||
@ -455,7 +455,7 @@ pub fn flood_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
|
||||
}
|
||||
|
||||
pub fn flood(&mut self, place: PlaceRef<'_>, map: &Map) {
|
||||
self.flood_with(place, map, V::top())
|
||||
self.flood_with(place, map, V::TOP)
|
||||
}
|
||||
|
||||
pub fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
|
||||
@ -468,7 +468,7 @@ pub fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
|
||||
}
|
||||
|
||||
pub fn flood_discr(&mut self, place: PlaceRef<'_>, map: &Map) {
|
||||
self.flood_discr_with(place, map, V::top())
|
||||
self.flood_discr_with(place, map, V::TOP)
|
||||
}
|
||||
|
||||
/// Low-level method that assigns to a place.
|
||||
@ -538,14 +538,14 @@ pub fn assign_discr(&mut self, target: PlaceRef<'_>, result: ValueOrPlace<V>, ma
|
||||
|
||||
/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
|
||||
pub fn get(&self, place: PlaceRef<'_>, map: &Map) -> V {
|
||||
map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::top())
|
||||
map.find(place).map(|place| self.get_idx(place, map)).unwrap_or(V::TOP)
|
||||
}
|
||||
|
||||
/// Retrieve the value stored for a place, or ⊤ if it is not tracked.
|
||||
pub fn get_discr(&self, place: PlaceRef<'_>, map: &Map) -> V {
|
||||
match map.find_discr(place) {
|
||||
Some(place) => self.get_idx(place, map),
|
||||
None => V::top(),
|
||||
None => V::TOP,
|
||||
}
|
||||
}
|
||||
|
||||
@ -553,11 +553,11 @@ pub fn get_discr(&self, place: PlaceRef<'_>, map: &Map) -> V {
|
||||
pub fn get_idx(&self, place: PlaceIndex, map: &Map) -> V {
|
||||
match &self.0 {
|
||||
StateData::Reachable(values) => {
|
||||
map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::top())
|
||||
map.places[place].value_index.map(|v| values[v].clone()).unwrap_or(V::TOP)
|
||||
}
|
||||
StateData::Unreachable => {
|
||||
// Because this is unreachable, we can return any value we want.
|
||||
V::bottom()
|
||||
V::BOTTOM
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -909,9 +909,7 @@ pub enum ValueOrPlace<V> {
|
||||
}
|
||||
|
||||
impl<V: HasTop> ValueOrPlace<V> {
|
||||
pub fn top() -> Self {
|
||||
ValueOrPlace::Value(V::top())
|
||||
}
|
||||
pub const TOP: Self = ValueOrPlace::Value(V::TOP);
|
||||
}
|
||||
|
||||
/// The set of projection elements that can be used by a tracked place.
|
||||
|
@ -208,8 +208,8 @@ fn handle_rvalue(
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.map(|result| ValueOrPlace::Value(self.wrap_immediate(result, *ty)))
|
||||
.unwrap_or(ValueOrPlace::top()),
|
||||
_ => ValueOrPlace::top(),
|
||||
.unwrap_or(ValueOrPlace::TOP),
|
||||
_ => ValueOrPlace::TOP,
|
||||
},
|
||||
Rvalue::BinaryOp(op, box (left, right)) => {
|
||||
// Overflows must be ignored here.
|
||||
|
Loading…
Reference in New Issue
Block a user