From 9aa4f6acb2e769ab012ab2cd7114177d94351847 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 31 Jan 2023 17:14:04 +0000 Subject: MIR-Validate StorageLive. --- compiler/rustc_const_eval/src/transform/validate.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'compiler/rustc_const_eval') diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 3af2d0c4e66..be5b1aad13c 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -755,8 +755,19 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { self.fail(location, format!("explicit `{:?}` is forbidden", kind)); } } - StatementKind::StorageLive(..) - | StatementKind::StorageDead(..) + StatementKind::StorageLive(local) => { + if self.reachable_blocks.contains(location.block) { + self.storage_liveness.seek_before_primary_effect(location); + let locals_with_storage = self.storage_liveness.get(); + if locals_with_storage.contains(*local) { + self.fail( + location, + format!("StorageLive({local:?}) which already has storage here"), + ); + } + } + } + StatementKind::StorageDead(_) | StatementKind::Coverage(_) | StatementKind::ConstEvalCounter | StatementKind::Nop => {} -- cgit 1.4.1-3-g733a5 From bf46b9cb281cd196ca6227b2b72ef64dee390b5a Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 25 Feb 2023 16:29:06 +0000 Subject: Explain that this is UB catching instead of malformed MIR. --- compiler/rustc_const_eval/src/transform/validate.rs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'compiler/rustc_const_eval') diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index be5b1aad13c..b12a63f23fa 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -756,6 +756,13 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } StatementKind::StorageLive(local) => { + // We check that the local is not live when entering a `StorageLive` for it. + // Technically, violating this restriction is only UB and not actually indicative + // of not well-formed MIR. This means that an optimization which turns MIR that + // already has UB into MIR that fails this check is not necessarily wrong. However, + // we have no such optimizations at the moment, and so we include this check anyway + // to help us catch bugs. If you happen to write an optimization that might cause + // this to incorrectly fire, feel free to remove this check. if self.reachable_blocks.contains(location.block) { self.storage_liveness.seek_before_primary_effect(location); let locals_with_storage = self.storage_liveness.get(); -- cgit 1.4.1-3-g733a5