From: David Henningsson Date: Tue, 19 Dec 2017 00:17:16 +0000 (+0100) Subject: Mir: Add Terminatorkind::Abort X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=dd6127e4af0a0b899c82944b023bf3e7e2949175;p=rust.git Mir: Add Terminatorkind::Abort The Abort Terminatorkind will cause an llvm.trap function call to be emitted. Signed-off-by: David Henningsson --- diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index df67c3abbe8..7517281b0b2 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -150,6 +150,7 @@ fn hash_stable(&self, targets.hash_stable(hcx, hasher); } mir::TerminatorKind::Resume | + mir::TerminatorKind::Abort | mir::TerminatorKind::Return | mir::TerminatorKind::GeneratorDrop | mir::TerminatorKind::Unreachable => {} diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index f410865a6cd..befab6d436b 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -637,6 +637,10 @@ pub enum TerminatorKind<'tcx> { /// continue. Emitted by build::scope::diverge_cleanup. Resume, + /// Indicates that the landing pad is finished and that the process + /// should abort. Used to prevent unwinding for foreign items. + Abort, + /// Indicates a normal return. The return place should have /// been filled in by now. This should occur at most once. Return, @@ -759,7 +763,7 @@ pub fn successors(&self) -> Cow<[BasicBlock]> { match *self { Goto { target: ref b } => slice::from_ref(b).into_cow(), SwitchInt { targets: ref b, .. } => b[..].into_cow(), - Resume | GeneratorDrop => (&[]).into_cow(), + Resume | Abort | GeneratorDrop => (&[]).into_cow(), Return => (&[]).into_cow(), Unreachable => (&[]).into_cow(), Call { destination: Some((_, t)), cleanup: Some(c), .. } => vec![t, c].into_cow(), @@ -794,7 +798,7 @@ pub fn successors_mut(&mut self) -> Vec<&mut BasicBlock> { match *self { Goto { target: ref mut b } => vec![b], SwitchInt { targets: ref mut b, .. } => b.iter_mut().collect(), - Resume | GeneratorDrop => Vec::new(), + Resume | Abort | GeneratorDrop => Vec::new(), Return => Vec::new(), Unreachable => Vec::new(), Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut c), .. } => vec![t, c], @@ -823,6 +827,7 @@ pub fn unwind_mut(&mut self) -> Option<&mut Option> { match *self { TerminatorKind::Goto { .. } | TerminatorKind::Resume | + TerminatorKind::Abort | TerminatorKind::Return | TerminatorKind::Unreachable | TerminatorKind::GeneratorDrop | @@ -918,6 +923,7 @@ pub fn fmt_head(&self, fmt: &mut W) -> fmt::Result { Return => write!(fmt, "return"), GeneratorDrop => write!(fmt, "generator_drop"), Resume => write!(fmt, "resume"), + Abort => write!(fmt, "abort"), Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value), Unreachable => write!(fmt, "unreachable"), Drop { ref location, .. } => write!(fmt, "drop({:?})", location), @@ -970,7 +976,7 @@ pub fn fmt_head(&self, fmt: &mut W) -> fmt::Result { pub fn fmt_successor_labels(&self) -> Vec> { use self::TerminatorKind::*; match *self { - Return | Resume | Unreachable | GeneratorDrop => vec![], + Return | Resume | Abort | Unreachable | GeneratorDrop => vec![], Goto { .. } => vec!["".into()], SwitchInt { ref values, .. } => { values.iter() @@ -2102,6 +2108,7 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) }, GeneratorDrop => GeneratorDrop, Resume => Resume, + Abort => Abort, Return => Return, Unreachable => Unreachable, FalseEdges { real_target, ref imaginary_targets } => @@ -2143,6 +2150,7 @@ fn super_visit_with>(&self, visitor: &mut V) -> bool { }, Goto { .. } | Resume | + Abort | Return | GeneratorDrop | Unreachable | diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 0e6c14af1ec..2a3f7384de2 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -432,6 +432,7 @@ fn super_terminator_kind(&mut self, } TerminatorKind::Resume | + TerminatorKind::Abort | TerminatorKind::Return | TerminatorKind::GeneratorDrop | TerminatorKind::Unreachable => { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index c907c97d6d3..672ab8257ba 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -557,6 +557,7 @@ fn visit_terminator_entry( }); } TerminatorKind::Goto { target: _ } + | TerminatorKind::Abort | TerminatorKind::Unreachable | TerminatorKind::FalseEdges { .. } => { // no data used, thus irrelevant to borrowck diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 4c8a171299f..901b73c610e 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -780,6 +780,7 @@ fn check_terminator( match term.kind { TerminatorKind::Goto { .. } | TerminatorKind::Resume + | TerminatorKind::Abort | TerminatorKind::Return | TerminatorKind::GeneratorDrop | TerminatorKind::Unreachable @@ -1082,6 +1083,9 @@ fn check_iscleanup(&mut self, mir: &Mir<'tcx>, block_data: &BasicBlockData<'tcx> TerminatorKind::Resume => if !is_cleanup { span_mirbug!(self, block_data, "resume on non-cleanup block!") }, + TerminatorKind::Abort => if !is_cleanup { + span_mirbug!(self, block_data, "abort on non-cleanup block!") + }, TerminatorKind::Return => if is_cleanup { span_mirbug!(self, block_data, "return on cleanup block") }, diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 25e4b30da80..cf121643a7e 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -465,6 +465,7 @@ fn terminator_effect_on_borrows(&self, } } } + mir::TerminatorKind::Abort | mir::TerminatorKind::SwitchInt {..} | mir::TerminatorKind::Drop {..} | mir::TerminatorKind::DropAndReplace {..} | diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 83c46e0199e..1597ba8aaa0 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -771,6 +771,7 @@ fn propagate_bits_into_graph_successors_of( match bb_data.terminator().kind { mir::TerminatorKind::Return | mir::TerminatorKind::Resume | + mir::TerminatorKind::Abort | mir::TerminatorKind::GeneratorDrop | mir::TerminatorKind::Unreachable => {} mir::TerminatorKind::Goto { ref target } | diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index c20beb7d8c2..f35e52497ce 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -334,6 +334,7 @@ fn gather_terminator(&mut self, term: &Terminator<'tcx>) { match term.kind { TerminatorKind::Goto { target: _ } | TerminatorKind::Resume | + TerminatorKind::Abort | TerminatorKind::GeneratorDrop | TerminatorKind::FalseEdges { .. } | TerminatorKind::Unreachable => { } diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index 3eef0578360..c8a0dbdd903 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -163,6 +163,7 @@ pub(super) fn eval_terminator( GeneratorDrop => unimplemented!(), DropAndReplace { .. } => unimplemented!(), Resume => unimplemented!(), + Abort => unimplemented!(), FalseEdges { .. } => bug!("should have been eliminated by `simplify_branches` mir pass"), Unreachable => return err!(Unreachable), } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 44dedde5229..62740a55dd6 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -625,6 +625,7 @@ fn visit_terminator_kind(&mut self, mir::TerminatorKind::Goto { .. } | mir::TerminatorKind::SwitchInt { .. } | mir::TerminatorKind::Resume | + mir::TerminatorKind::Abort | mir::TerminatorKind::Return | mir::TerminatorKind::Unreachable | mir::TerminatorKind::Assert { .. } => {} diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index e7ce5285071..e9ba5de3cc6 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -73,6 +73,7 @@ fn visit_terminator(&mut self, TerminatorKind::DropAndReplace { .. } | TerminatorKind::GeneratorDrop | TerminatorKind::Resume | + TerminatorKind::Abort | TerminatorKind::Return | TerminatorKind::Unreachable | TerminatorKind::FalseEdges { .. } => { diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 72163847952..43ee75d1e2b 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -806,6 +806,7 @@ fn visit_terminator_kind(&mut self, block: BasicBlock, *kind = TerminatorKind::Goto { target: tgt } } } + TerminatorKind::Abort => { } TerminatorKind::Unreachable => { } TerminatorKind::FalseEdges { ref mut real_target, ref mut imaginary_targets } => { *real_target = self.update_target(*real_target); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 2b2323928ef..f0871bb188d 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -324,6 +324,7 @@ fn qualify_const(&mut self) -> (Qualif, Rc>) { TerminatorKind::SwitchInt {..} | TerminatorKind::DropAndReplace { .. } | TerminatorKind::Resume | + TerminatorKind::Abort | TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } | TerminatorKind::Unreachable | diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index d29174d5719..23274cdedf2 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -76,6 +76,7 @@ fn is_nop_landing_pad(&self, bb: BasicBlock, mir: &Mir, nop_landing_pads: &BitVe TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } | TerminatorKind::Return | + TerminatorKind::Abort | TerminatorKind::Unreachable | TerminatorKind::Call { .. } | TerminatorKind::Assert { .. } | diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs index 8a9936ecb8b..b379a174b23 100644 --- a/src/librustc_passes/mir_stats.rs +++ b/src/librustc_passes/mir_stats.rs @@ -113,6 +113,7 @@ fn visit_terminator_kind(&mut self, TerminatorKind::Goto { .. } => "TerminatorKind::Goto", TerminatorKind::SwitchInt { .. } => "TerminatorKind::SwitchInt", TerminatorKind::Resume => "TerminatorKind::Resume", + TerminatorKind::Abort => "TerminatorKind::Abort", TerminatorKind::Return => "TerminatorKind::Return", TerminatorKind::Unreachable => "TerminatorKind::Unreachable", TerminatorKind::Drop { .. } => "TerminatorKind::Drop", diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index cfe55aba0d3..31cbb07dbe6 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -236,6 +236,7 @@ fn discover_masters<'tcx>(result: &mut IndexVec, match data.terminator().kind { TerminatorKind::Goto { .. } | TerminatorKind::Resume | + TerminatorKind::Abort | TerminatorKind::Return | TerminatorKind::GeneratorDrop | TerminatorKind::Unreachable | diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs index 1cb3a66e4d8..422b8210b35 100644 --- a/src/librustc_trans/mir/block.rs +++ b/src/librustc_trans/mir/block.rs @@ -180,6 +180,13 @@ fn trans_terminator(&mut self, } } + mir::TerminatorKind::Abort => { + // Call core::intrinsics::abort() + let fnname = bcx.ccx.get_intrinsic(&("llvm.trap")); + bcx.call(fnname, &[], None); + bcx.unreachable(); + } + mir::TerminatorKind::Goto { target } => { funclet_br(self, bcx, target); }