Add initial AST and MIR support for unwinding from inline assembly

This commit is contained in:
Amanieu d'Antras
2021-08-30 01:23:33 +01:00
committed by cynecx
parent 532d2b14c0
commit 940b2eabad
39 changed files with 355 additions and 212 deletions

View File

@@ -160,9 +160,7 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
&self,
state: &mut Self::Domain,
block: BasicBlock,
func: &mir::Operand<'tcx>,
args: &[mir::Operand<'tcx>],
return_place: mir::Place<'tcx>,
return_places: CallReturnPlaces<'_, 'tcx>,
);
/// Updates the current dataflow state with the effect of resuming from a `Yield` terminator.
@@ -276,9 +274,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
&self,
trans: &mut impl GenKill<Self::Idx>,
block: BasicBlock,
func: &mir::Operand<'tcx>,
args: &[mir::Operand<'tcx>],
return_place: mir::Place<'tcx>,
return_places: CallReturnPlaces<'_, 'tcx>,
);
/// See `Analysis::apply_yield_resume_effect`.
@@ -347,11 +343,9 @@ where
&self,
state: &mut A::Domain,
block: BasicBlock,
func: &mir::Operand<'tcx>,
args: &[mir::Operand<'tcx>],
return_place: mir::Place<'tcx>,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
self.call_return_effect(state, block, func, args, return_place);
self.call_return_effect(state, block, return_places);
}
fn apply_yield_resume_effect(
@@ -542,5 +536,29 @@ pub trait SwitchIntEdgeEffects<D> {
fn apply(&mut self, apply_edge_effect: impl FnMut(&mut D, SwitchIntTarget));
}
/// List of places that are written to after a successful (non-unwind) return
/// from a `Call` or `InlineAsm`.
pub enum CallReturnPlaces<'a, 'tcx> {
Call(mir::Place<'tcx>),
InlineAsm(&'a [mir::InlineAsmOperand<'tcx>]),
}
impl<'tcx> CallReturnPlaces<'_, 'tcx> {
pub fn for_each(&self, mut f: impl FnMut(mir::Place<'tcx>)) {
match *self {
Self::Call(place) => f(place),
Self::InlineAsm(operands) => {
for op in operands {
match *op {
mir::InlineAsmOperand::Out { place: Some(place), .. }
| mir::InlineAsmOperand::InOut { out_place: Some(place), .. } => f(place),
_ => {}
}
}
}
}
}
}
#[cfg(test)]
mod tests;