diff options
| author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-02-01 00:00:00 +0000 |
|---|---|---|
| committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-02-01 00:00:00 +0000 |
| commit | 22872e508f32158a0f325ab1b3399c00de081ff7 (patch) | |
| tree | d59db38416a1a7b85a796389a1131eb0bee6d6d4 /compiler/rustc_const_eval/src | |
| parent | 547f2ba06bc4aa93a375c54e1af3fd1216eeaf62 (diff) | |
| download | rust-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.rs | 18 |
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); |
