Add initial AST and MIR support for unwinding from inline assembly
This commit is contained in:
parent
532d2b14c0
commit
940b2eabad
39 changed files with 355 additions and 212 deletions
|
@ -208,6 +208,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
|||
MutatingUseContext::Store
|
||||
| MutatingUseContext::Drop
|
||||
| MutatingUseContext::AsmOutput
|
||||
| MutatingUseContext::LlvmAsmOutput
|
||||
)
|
||||
);
|
||||
// If this is just an assignment, determine if the assigned type needs dropping.
|
||||
|
|
|
@ -1022,6 +1022,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
|
|||
// These are just stores, where the storing is not propagatable, but there may be later
|
||||
// mutations of the same local via `Store`
|
||||
| MutatingUse(MutatingUseContext::Call)
|
||||
| MutatingUse(MutatingUseContext::AsmOutput)
|
||||
// Actual store that can possibly even propagate a value
|
||||
| MutatingUse(MutatingUseContext::Store) => {
|
||||
if !self.found_assignment.insert(local) {
|
||||
|
@ -1052,7 +1053,7 @@ impl<'tcx> Visitor<'tcx> for CanConstProp {
|
|||
|
||||
// These could be propagated with a smarter analysis or just some careful thinking about
|
||||
// whether they'd be fine right now.
|
||||
MutatingUse(MutatingUseContext::AsmOutput)
|
||||
MutatingUse(MutatingUseContext::LlvmAsmOutput)
|
||||
| MutatingUse(MutatingUseContext::Yield)
|
||||
| MutatingUse(MutatingUseContext::Drop)
|
||||
| MutatingUse(MutatingUseContext::Retag)
|
||||
|
|
|
@ -624,6 +624,7 @@ impl Conflicts<'a> {
|
|||
options: _,
|
||||
line_spans: _,
|
||||
destination: _,
|
||||
cleanup: _,
|
||||
} => {
|
||||
// The intended semantics here aren't documented, we just assume that nothing that
|
||||
// could be written to by the assembly may overlap with any other operands.
|
||||
|
|
|
@ -441,6 +441,13 @@ impl Inliner<'tcx> {
|
|||
}
|
||||
}
|
||||
TerminatorKind::Resume => cost += RESUME_PENALTY,
|
||||
TerminatorKind::InlineAsm { cleanup, .. } => {
|
||||
cost += INSTR_COST;
|
||||
|
||||
if cleanup.is_some() {
|
||||
cost += LANDINGPAD_PENALTY;
|
||||
}
|
||||
}
|
||||
_ => cost += INSTR_COST,
|
||||
}
|
||||
|
||||
|
@ -954,9 +961,13 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
|
|||
{
|
||||
bug!("False unwinds should have been removed before inlining")
|
||||
}
|
||||
TerminatorKind::InlineAsm { ref mut destination, .. } => {
|
||||
TerminatorKind::InlineAsm { ref mut destination, ref mut cleanup, .. } => {
|
||||
if let Some(ref mut tgt) = *destination {
|
||||
*tgt = self.map_block(*tgt);
|
||||
} else if !self.in_cleanup_block {
|
||||
// Unless this inline asm is in a cleanup block, add an unwind edge to
|
||||
// the original call's cleanup block
|
||||
*cleanup = self.cleanup_block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue