struct InitializedBeforeUse;Expand description
Backward dataflow analysis which answers the question: from this point, is there a path whose first access to a local is an initialization?
This is used when a local is dead in a predecessor but maybe-live in its
successor. A StorageLive is inserted on that edge only if some continuation
initializes the local before reading it. If every continuation instead
reads the local first or never accesses it, StorageLive would be
unnecessary: it only allocates uninitialized storage and cannot make the
read valid.
For example:
bb1 bb2
StorageLive(_1); _1 = ... // _1 is dead
_flag = true _flag = false
\ /
\ /
bb3
switchInt(_flag)
/ \
bb4: use(_1) bb5: no useLiveness is path-insensitive, so _1 is maybe-live in bb3: it is live in
bb1 and bb4, but dead in bb2 and bb5. Nevertheless, no StorageLive
is needed on bb2 -> bb3. The continuation to bb5 never accesses _1,
while the continuation to bb4 reads _1 without initializing it first and
is therefore already UB. (The _flag assignments make that latter
continuation dynamically impossible, but this analysis does not need to
prove the correlation.)
Live ranges which start in the middle of a block do not need this analysis:
such ranges always start at an initialization, so a StorageLive is
unconditionally required there.
This analysis deliberately ignores the reconstructed StorageDead
boundaries. This can cause an initialization from a later allocation range
to propagate into an earlier range and result in an unnecessary
StorageLive, but cannot cause a required StorageLive to be omitted.
Implementations§
Source§impl InitializedBeforeUse
impl InitializedBeforeUse
Sourcefn compute<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
) -> IndexVec<BasicBlock, DenseBitSet<Local>>
fn compute<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, ) -> IndexVec<BasicBlock, DenseBitSet<Local>>
Computes the analysis state at the start of each block.
Trait Implementations§
Source§impl<'tcx> Analysis<'tcx> for InitializedBeforeUse
impl<'tcx> Analysis<'tcx> for InitializedBeforeUse
Source§const NAME: &'static str = "initialized-before-use"
const NAME: &'static str = "initialized-before-use"
Source§type Domain = DenseBitSet<Local>
type Domain = DenseBitSet<Local>
Source§fn bottom_value(&self, body: &Body<'tcx>) -> Self::Domain
fn bottom_value(&self, body: &Body<'tcx>) -> Self::Domain
Source§fn initialize_start_block(&self, _body: &Body<'tcx>, _state: &mut Self::Domain)
fn initialize_start_block(&self, _body: &Body<'tcx>, _state: &mut Self::Domain)
START_BLOCK. Read moreSource§fn apply_primary_statement_effect(
&self,
state: &mut Self::Domain,
statement: &Statement<'tcx>,
location: Location,
)
fn apply_primary_statement_effect( &self, state: &mut Self::Domain, statement: &Statement<'tcx>, location: Location, )
Source§fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &Terminator<'tcx>,
location: Location,
)
fn apply_primary_terminator_effect( &self, state: &mut Self::Domain, terminator: &Terminator<'tcx>, location: Location, )
Source§type SwitchIntData = !
type SwitchIntData = !
SwitchInt terminators, if necessary.Source§fn apply_effect<'mir>(
&self,
state: &mut Self::Domain,
block: BasicBlock,
block_data: &'mir BasicBlockData<'tcx>,
idx: EffectIndex,
)
fn apply_effect<'mir>( &self, state: &mut Self::Domain, block: BasicBlock, block_data: &'mir BasicBlockData<'tcx>, idx: EffectIndex, )
EffectIndex, calls the appropriate apply_* method in the
{early,primary} x {statement,terminator} space. Read moreSource§fn apply_early_statement_effect(
&self,
_state: &mut Self::Domain,
_statement: &Statement<'tcx>,
_location: Location,
)
fn apply_early_statement_effect( &self, _state: &mut Self::Domain, _statement: &Statement<'tcx>, _location: Location, )
Source§fn apply_early_terminator_effect(
&self,
_state: &mut Self::Domain,
_terminator: &Terminator<'tcx>,
_location: Location,
)
fn apply_early_terminator_effect( &self, _state: &mut Self::Domain, _terminator: &Terminator<'tcx>, _location: Location, )
Source§fn get_terminator_edges<'mir>(
&self,
_state: &Self::Domain,
terminator: &'mir Terminator<'tcx>,
_location: Location,
) -> TerminatorEdges<'mir, 'tcx>
fn get_terminator_edges<'mir>( &self, _state: &Self::Domain, terminator: &'mir Terminator<'tcx>, _location: Location, ) -> TerminatorEdges<'mir, 'tcx>
apply_primary_terminator_effect is applied; this might seem strange but in practice
MaybeInitializedPlaces needs that ordering and other analyses work with either ordering.Source§fn apply_call_return_effect(
&self,
_state: &mut Self::Domain,
_block: BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
)
fn apply_call_return_effect( &self, _state: &mut Self::Domain, _block: BasicBlock, _return_places: CallReturnPlaces<'_, 'tcx>, )
Call
terminator. Read moreSource§fn get_switch_int_data(
&self,
_block: BasicBlock,
_targets: &SwitchTargets,
_discr: &Operand<'tcx>,
) -> Option<Self::SwitchIntData>
fn get_switch_int_data( &self, _block: BasicBlock, _targets: &SwitchTargets, _discr: &Operand<'tcx>, ) -> Option<Self::SwitchIntData>
SwitchInt terminator. Read moreSource§fn apply_switch_int_edge_effect(
&self,
_state: &mut Self::Domain,
_data: &Self::SwitchIntData,
_target_idx: SwitchTargetIndex,
)
fn apply_switch_int_edge_effect( &self, _state: &mut Self::Domain, _data: &Self::SwitchIntData, _target_idx: SwitchTargetIndex, )
get_switch_int_data.Auto Trait Implementations§
impl DynSend for InitializedBeforeUse
impl DynSync for InitializedBeforeUse
impl Forget for InitializedBeforeUse
impl Freeze for InitializedBeforeUse
impl RefUnwindSafe for InitializedBeforeUse
impl Send for InitializedBeforeUse
impl Sync for InitializedBeforeUse
impl Unpin for InitializedBeforeUse
impl UnsafeUnpin for InitializedBeforeUse
impl UnwindSafe for InitializedBeforeUse
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
Source§impl<T, R> CollectAndApply<T, R> for T
impl<T, R> CollectAndApply<T, R> for T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<K> IntoQueryKey<K> for K
impl<K> IntoQueryKey<K> for K
Source§fn into_query_key(self) -> K
fn into_query_key(self) -> K
Self to K.
This should always be a very cheap conversion, e.g. LocalDefId::to_def_id.Source§impl<T> MaybeResult<T> for T
impl<T> MaybeResult<T> for T
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
impl<I, T, U> Upcast<I, U> for Twhere
U: UpcastFrom<I, T>,
Source§impl<I, T> UpcastFrom<I, T> for T
impl<I, T> UpcastFrom<I, T> for T
fn upcast_from(from: T, _tcx: I) -> T
Source§impl<T> WithSubscriber for T
impl<T> WithSubscriber for T
Source§fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
Source§fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 0 bytes