From c0c13b709e4a5ffb2ef1799d606719b4b5ad9e3a Mon Sep 17 00:00:00 2001 From: Jakob Degen Date: Sun, 12 Dec 2021 17:28:19 -0500 Subject: [PATCH] Improve test coverage of `early_otherwise_branch` mir opt --- ...ess.no_deref_ptr.EarlyOtherwiseBranch.diff | 43 +++++++++++++++++++ ...ness.no_downcast.EarlyOtherwiseBranch.diff | 30 +++++++++++++ .../early_otherwise_branch_soundness.rs | 32 ++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff create mode 100644 src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff create mode 100644 src/test/mir-opt/early_otherwise_branch_soundness.rs diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff new file mode 100644 index 0000000000000..a272266066246 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff @@ -0,0 +1,43 @@ +- // MIR for `no_deref_ptr` before EarlyOtherwiseBranch ++ // MIR for `no_deref_ptr` after EarlyOtherwiseBranch + + fn no_deref_ptr(_1: Option, _2: *const Option) -> i32 { + debug a => _1; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:18:24: 18:25 + debug b => _2; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:18:40: 18:41 + let mut _0: i32; // return place in scope 0 at $DIR/early_otherwise_branch_soundness.rs:18:66: 18:69 + let mut _3: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:21:9: 21:16 + let mut _4: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:13: 22:20 + let _5: i32; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:18: 22:19 + scope 1 { + debug v => _5; // in scope 1 at $DIR/early_otherwise_branch_soundness.rs:22:18: 22:19 + } + + bb0: { + _3 = discriminant(_1); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:19:11: 19:12 + switchInt(move _3) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:19:5: 19:12 + } + + bb1: { + _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15 + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15 + } + + bb2: { + _4 = discriminant((*_2)); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:21:26: 21:28 + switchInt(move _4) -> [1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:21:20: 21:28 + } + + bb3: { + _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19 + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19 + } + + bb4: { + StorageLive(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:18: 22:19 + _5 = (((*_2) as Some).0: i32); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:18: 22:19 + _0 = _5; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25 + StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25 + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff new file mode 100644 index 0000000000000..56b7c9a2db478 --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -0,0 +1,30 @@ +- // MIR for `no_downcast` before EarlyOtherwiseBranch ++ // MIR for `no_downcast` after EarlyOtherwiseBranch + + fn no_downcast(_1: &E) -> u32 { + debug e => _1; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:12:16: 12:17 + let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_soundness.rs:12:26: 12:29 + let mut _2: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:20: 13:30 + let mut _3: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + + bb0: { + _3 = discriminant((*_1)); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + switchInt(move _3) -> [1_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + } + + bb1: { + _2 = discriminant((*(((*_1) as Some).0: &E))); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + } + + bb2: { + _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:38: 13:39 + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52 + } + + bb3: { + _0 = const 2_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:49: 13:50 + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52 + } + } + diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.rs b/src/test/mir-opt/early_otherwise_branch_soundness.rs new file mode 100644 index 0000000000000..d2513213d796f --- /dev/null +++ b/src/test/mir-opt/early_otherwise_branch_soundness.rs @@ -0,0 +1,32 @@ +// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts + +// Tests various cases that the `early_otherwise_branch` opt should *not* optimize + +// From #78496 +enum E<'a> { + Empty, + Some(&'a E<'a>), +} + +// EMIT_MIR early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff +fn no_downcast(e: &E) -> u32 { + if let E::Some(E::Some(_)) = e { 1 } else { 2 } +} + +// SAFETY: if `a` is `Some`, `b` must point to a valid, initialized value +// EMIT_MIR early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff +unsafe fn no_deref_ptr(a: Option, b: *const Option) -> i32 { + match a { + // `*b` being correct depends on `a == Some(_)` + Some(_) => match *b { + Some(v) => v, + _ => 0, + }, + _ => 0, + } +} + +fn main() { + no_downcast(&E::Empty); + unsafe { no_deref_ptr(None, std::ptr::null()) }; +}