about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2022-02-01 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2022-02-01 00:00:00 +0000
commit22872e508f32158a0f325ab1b3399c00de081ff7 (patch)
treed59db38416a1a7b85a796389a1131eb0bee6d6d4 /compiler/rustc_const_eval/src
parent547f2ba06bc4aa93a375c54e1af3fd1216eeaf62 (diff)
downloadrust-22872e508f32158a0f325ab1b3399c00de081ff7.tar.gz
rust-22872e508f32158a0f325ab1b3399c00de081ff7.zip
Validate that values in switch int terminator are unique
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs18
1 files changed, 18 insertions, 0 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 22ef0b2dda5..cf15fc4ddc3 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -55,6 +55,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
             reachable_blocks: traversal::reachable_as_bitset(body),
             storage_liveness,
             place_cache: Vec::new(),
+            value_cache: Vec::new(),
         }
         .visit_body(body);
     }
@@ -109,6 +110,7 @@ struct TypeChecker<'a, 'tcx> {
     reachable_blocks: BitSet<BasicBlock>,
     storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive>,
     place_cache: Vec<PlaceRef<'tcx>>,
+    value_cache: Vec<u128>,
 }
 
 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@@ -398,6 +400,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     self.check_edge(location, target, EdgeKind::Normal);
                 }
                 self.check_edge(location, targets.otherwise(), EdgeKind::Normal);
+
+                self.value_cache.clear();
+                self.value_cache.extend(targets.iter().map(|(value, _)| value));
+                let all_len = self.value_cache.len();
+                self.value_cache.sort_unstable();
+                self.value_cache.dedup();
+                let has_duplicates = all_len != self.value_cache.len();
+                if has_duplicates {
+                    self.fail(
+                        location,
+                        format!(
+                            "duplicated values in `SwitchInt` terminator: {:?}",
+                            terminator.kind,
+                        ),
+                    );
+                }
             }
             TerminatorKind::Drop { target, unwind, .. } => {
                 self.check_edge(location, *target, EdgeKind::Normal);