From 22872e508f32158a0f325ab1b3399c00de081ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 1 Feb 2022 00:00:00 +0000 Subject: [PATCH] Validate that values in switch int terminator are unique --- .../rustc_const_eval/src/transform/validate.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 22ef0b2dda506..cf15fc4ddc3a5 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, storage_liveness: ResultsCursor<'a, 'tcx, MaybeStorageLive>, place_cache: Vec>, + value_cache: Vec, } 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);