about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-02-02 19:34:04 +0100
committerGitHub <noreply@github.com>2022-02-02 19:34:04 +0100
commitb53eaf7ce5f791c4af127468ffef78fe3fa313b4 (patch)
treea2374c780d012d25c1cad0f48e5c98a4060ded39
parent7e212c1ca9aa715a51ed4e6a60f3b0c837634720 (diff)
parent22872e508f32158a0f325ab1b3399c00de081ff7 (diff)
downloadrust-b53eaf7ce5f791c4af127468ffef78fe3fa313b4.tar.gz
rust-b53eaf7ce5f791c4af127468ffef78fe3fa313b4.zip
Rollup merge of #93546 - tmiasko:validate-switch-int, r=oli-obk
Validate that values in switch int terminator are unique
-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);