Skip to content

Commit 3af45d6

Browse files
committed
Address review feedback
1 parent e3f2edc commit 3af45d6

File tree

7 files changed

+40
-31
lines changed

7 files changed

+40
-31
lines changed

compiler/rustc_codegen_ssa/src/mir/block.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
147147
}
148148

149149
/// Call `fn_ptr` of `fn_abi` with the arguments `llargs`, the optional
150-
/// return destination `destination` and the cleanup function `cleanup`.
150+
/// return destination `destination` and the unwind action `unwind`.
151151
fn do_call<Bx: BuilderMethods<'a, 'tcx>>(
152152
&self,
153153
fx: &mut FunctionCx<'a, 'tcx, Bx>,
@@ -234,7 +234,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
234234
}
235235
}
236236

237-
/// Generates inline assembly with optional `destination` and `cleanup`.
237+
/// Generates inline assembly with optional `destination` and `unwind`.
238238
fn do_inlineasm<Bx: BuilderMethods<'a, 'tcx>>(
239239
&self,
240240
fx: &mut FunctionCx<'a, 'tcx, Bx>,

compiler/rustc_const_eval/src/transform/validate.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,24 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
232232
}
233233
}
234234

235+
fn check_unwind_edge(&mut self, location: Location, unwind: UnwindAction) {
236+
let is_cleanup = self.body.basic_blocks[location.block].is_cleanup;
237+
match unwind {
238+
UnwindAction::Cleanup(unwind) => {
239+
if is_cleanup {
240+
self.fail(location, "unwind on cleanup block");
241+
}
242+
self.check_edge(location, unwind, EdgeKind::Unwind);
243+
}
244+
UnwindAction::Continue => {
245+
if is_cleanup {
246+
self.fail(location, "unwind on cleanup block");
247+
}
248+
}
249+
UnwindAction::Unreachable | UnwindAction::Terminate => (),
250+
}
251+
}
252+
235253
/// Check if src can be assigned into dest.
236254
/// This is not precise, it will accept some incorrect assignments.
237255
fn mir_assign_valid_types(&self, src: Ty<'tcx>, dest: Ty<'tcx>) -> bool {
@@ -902,9 +920,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
902920
}
903921
TerminatorKind::Drop { target, unwind, .. } => {
904922
self.check_edge(location, *target, EdgeKind::Normal);
905-
if let UnwindAction::Cleanup(unwind) = unwind {
906-
self.check_edge(location, *unwind, EdgeKind::Unwind);
907-
}
923+
self.check_unwind_edge(location, *unwind);
908924
}
909925
TerminatorKind::Call { func, args, destination, target, unwind, .. } => {
910926
let func_ty = func.ty(&self.body.local_decls, self.tcx);
@@ -918,9 +934,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
918934
if let Some(target) = target {
919935
self.check_edge(location, *target, EdgeKind::Normal);
920936
}
921-
if let UnwindAction::Cleanup(cleanup) = unwind {
922-
self.check_edge(location, *cleanup, EdgeKind::Unwind);
923-
}
937+
self.check_unwind_edge(location, *unwind);
924938

925939
// The call destination place and Operand::Move place used as an argument might be
926940
// passed by a reference to the callee. Consequently they must be non-overlapping.
@@ -958,9 +972,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
958972
);
959973
}
960974
self.check_edge(location, *target, EdgeKind::Normal);
961-
if let UnwindAction::Cleanup(cleanup) = unwind {
962-
self.check_edge(location, *cleanup, EdgeKind::Unwind);
963-
}
975+
self.check_unwind_edge(location, *unwind);
964976
}
965977
TerminatorKind::Yield { resume, drop, .. } => {
966978
if self.body.generator.is_none() {
@@ -992,17 +1004,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
9921004
);
9931005
}
9941006
self.check_edge(location, *real_target, EdgeKind::Normal);
995-
if let UnwindAction::Cleanup(unwind) = unwind {
996-
self.check_edge(location, *unwind, EdgeKind::Unwind);
997-
}
1007+
self.check_unwind_edge(location, *unwind);
9981008
}
9991009
TerminatorKind::InlineAsm { destination, unwind, .. } => {
10001010
if let Some(destination) = destination {
10011011
self.check_edge(location, *destination, EdgeKind::Normal);
10021012
}
1003-
if let UnwindAction::Cleanup(cleanup) = unwind {
1004-
self.check_edge(location, *cleanup, EdgeKind::Unwind);
1005-
}
1013+
self.check_unwind_edge(location, *unwind);
10061014
}
10071015
TerminatorKind::GeneratorDrop => {
10081016
if self.body.generator.is_none() {

compiler/rustc_middle/src/mir/patch.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub struct MirPatch<'tcx> {
1313
new_locals: Vec<LocalDecl<'tcx>>,
1414
resume_block: Option<BasicBlock>,
1515
// Only for unreachable in cleanup path.
16-
unreachable_block: Option<BasicBlock>,
16+
unreachable_cleanup_block: Option<BasicBlock>,
1717
terminate_block: Option<BasicBlock>,
1818
body_span: Span,
1919
next_local: usize,
@@ -28,7 +28,7 @@ impl<'tcx> MirPatch<'tcx> {
2828
new_locals: vec![],
2929
next_local: body.local_decls.len(),
3030
resume_block: None,
31-
unreachable_block: None,
31+
unreachable_cleanup_block: None,
3232
terminate_block: None,
3333
body_span: body.span,
3434
};
@@ -41,8 +41,11 @@ impl<'tcx> MirPatch<'tcx> {
4141
}
4242

4343
// Check if we already have an unreachable block
44-
if let TerminatorKind::Unreachable = block.terminator().kind && block.statements.is_empty() {
45-
result.unreachable_block = Some(bb);
44+
if let TerminatorKind::Unreachable = block.terminator().kind
45+
&& block.statements.is_empty()
46+
&& block.is_cleanup
47+
{
48+
result.unreachable_cleanup_block = Some(bb);
4649
continue;
4750
}
4851

@@ -73,8 +76,8 @@ impl<'tcx> MirPatch<'tcx> {
7376
bb
7477
}
7578

76-
pub fn unreachable_block(&mut self) -> BasicBlock {
77-
if let Some(bb) = self.unreachable_block {
79+
pub fn unreachable_cleanup_block(&mut self) -> BasicBlock {
80+
if let Some(bb) = self.unreachable_cleanup_block {
7881
return bb;
7982
}
8083

@@ -86,7 +89,7 @@ impl<'tcx> MirPatch<'tcx> {
8689
}),
8790
is_cleanup: true,
8891
});
89-
self.unreachable_block = Some(bb);
92+
self.unreachable_cleanup_block = Some(bb);
9093
bb
9194
}
9295

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ pub struct CopyNonOverlapping<'tcx> {
523523
/// The basic block pointed to by a `Cleanup` unwind action must have its `cleanup` flag set.
524524
/// `cleanup` basic blocks have a couple restrictions:
525525
/// 1. All `unwind` fields in them must be `UnwindAction::Terminate` or `UnwindAction::Unreachable`.
526-
/// 2. `Return` terminators are not allowed in them. `Terminate` and `Unwind` terminators are.
526+
/// 2. `Return` terminators are not allowed in them. `Terminate` and `Resume` terminators are.
527527
/// 3. All other basic blocks (in the current body) that are reachable from `cleanup` basic blocks
528528
/// must also be `cleanup`. This is a part of the type system and checked statically, so it is
529529
/// still an error to have such an edge in the CFG even if it's known that it won't be taken at
@@ -721,8 +721,6 @@ pub enum TerminatorKind<'tcx> {
721721
/// consider it in borrowck. We don't want to accept programs which
722722
/// pass borrowck only when `panic=abort` or some assertions are disabled
723723
/// due to release vs. debug mode builds.
724-
/// This field does not necessary have to be `UnwindAction::Cleanup` because
725-
/// of the `remove_noop_landing_pads` and `abort_unwinding_calls` passes.
726724
unwind: UnwindAction,
727725
},
728726

compiler/rustc_mir_transform/src/elaborate_drops.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
415415
UnwindAction::Cleanup(cleanup) => Unwind::To(cleanup),
416416
UnwindAction::Continue => Unwind::To(self.patch.resume_block()),
417417
UnwindAction::Unreachable => {
418-
Unwind::To(self.patch.unreachable_block())
418+
Unwind::To(self.patch.unreachable_cleanup_block())
419419
}
420420
UnwindAction::Terminate => {
421421
Unwind::To(self.patch.terminate_block())

compiler/rustc_mir_transform/src/generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
10631063
Unwind::To(match *unwind {
10641064
UnwindAction::Cleanup(tgt) => tgt,
10651065
UnwindAction::Continue => elaborator.patch.resume_block(),
1066-
UnwindAction::Unreachable => elaborator.patch.unreachable_block(),
1066+
UnwindAction::Unreachable => elaborator.patch.unreachable_cleanup_block(),
10671067
UnwindAction::Terminate => elaborator.patch.terminate_block(),
10681068
})
10691069
};

compiler/rustc_mir_transform/src/shim.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
543543
TerminatorKind::Drop {
544544
place: dest_field,
545545
target: unwind,
546-
unwind: UnwindAction::Continue,
546+
unwind: UnwindAction::Terminate,
547547
},
548548
true,
549549
);
@@ -814,7 +814,7 @@ fn build_call_shim<'tcx>(
814814
TerminatorKind::Drop {
815815
place: rcvr_place(),
816816
target: BasicBlock::new(4),
817-
unwind: UnwindAction::Continue,
817+
unwind: UnwindAction::Terminate,
818818
},
819819
true,
820820
);

0 commit comments

Comments
 (0)