about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorJakob Degen <jakob.e.degen@gmail.com>2022-03-25 20:00:33 -0400
committerJakob Degen <jakob.e.degen@gmail.com>2022-04-11 15:22:32 -0400
commitf2d7908ff761c25e642e45fcabc820318e4ecf92 (patch)
tree50af7afee6db5c1f74d52fed3e4be4861e29b8f8 /compiler
parentf1f25c0f8145c45078ff628dedae6aa4b28d962d (diff)
downloadrust-f2d7908ff761c25e642e45fcabc820318e4ecf92.tar.gz
rust-f2d7908ff761c25e642e45fcabc820318e4ecf92.zip
Adjust MIR validator to check a few more things for terminators
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs24
1 files changed, 19 insertions, 5 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 7eb91385653..4358ec2fff7 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -642,6 +642,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             TerminatorKind::Yield { resume, drop, .. } => {
+                if self.body.generator.is_none() {
+                    self.fail(location, "`Yield` cannot appear outside generator bodies");
+                }
                 if self.mir_phase >= MirPhase::GeneratorsLowered {
                     self.fail(location, "`Yield` should have been replaced by generator lowering");
                 }
@@ -681,6 +684,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             TerminatorKind::GeneratorDrop => {
+                if self.body.generator.is_none() {
+                    self.fail(location, "`GeneratorDrop` cannot appear outside generator bodies");
+                }
                 if self.mir_phase >= MirPhase::GeneratorsLowered {
                     self.fail(
                         location,
@@ -688,11 +694,19 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     );
                 }
             }
-            // Nothing to validate for these.
-            TerminatorKind::Resume
-            | TerminatorKind::Abort
-            | TerminatorKind::Return
-            | TerminatorKind::Unreachable => {}
+            TerminatorKind::Resume | TerminatorKind::Abort => {
+                let bb = location.block;
+                if !self.body.basic_blocks()[bb].is_cleanup {
+                    self.fail(location, "Cannot `Resume` from non-cleanup basic block")
+                }
+            }
+            TerminatorKind::Return => {
+                let bb = location.block;
+                if self.body.basic_blocks()[bb].is_cleanup {
+                    self.fail(location, "Cannot `Return` from cleanup basic block")
+                }
+            }
+            TerminatorKind::Unreachable => {}
         }
 
         self.super_terminator(terminator, location);