diff options
| author | bors <bors@rust-lang.org> | 2018-11-02 12:45:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-11-02 12:45:03 +0000 |
| commit | 87a3c1ee7016bbfb782f2fd8adc75b46687ef929 (patch) | |
| tree | d1f5ce96602af0244456e01139806980d7730c8b /src/test | |
| parent | d0c869c323289c5ec4df83e1c9091fa0b3e2fc07 (diff) | |
| parent | d10304eeb5c9e63597b9ee1094aca0f63c4f31ca (diff) | |
| download | rust-87a3c1ee7016bbfb782f2fd8adc75b46687ef929.tar.gz rust-87a3c1ee7016bbfb782f2fd8adc75b46687ef929.zip | |
Auto merge of #55316 - RalfJung:retagging, r=oli-obk
Add Retagging statements This adds a `Retag` statement kind to MIR, used to perform the retagging operation from [Stacked Borrows](https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html). It also kills the old `Validate` statements that I added last year. NOTE: This includes https://github.com/rust-lang/rust/pull/55270. Only [these commits are new](https://github.com/RalfJung/rust/compare/stacked-borrows-ng...RalfJung:retagging).
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/mir-opt/inline-retag.rs | 45 | ||||
| -rw-r--r-- | src/test/mir-opt/retag.rs | 106 | ||||
| -rw-r--r-- | src/test/mir-opt/validate_1.rs | 76 | ||||
| -rw-r--r-- | src/test/mir-opt/validate_2.rs | 37 | ||||
| -rw-r--r-- | src/test/mir-opt/validate_3.rs | 77 | ||||
| -rw-r--r-- | src/test/mir-opt/validate_4.rs | 90 | ||||
| -rw-r--r-- | src/test/mir-opt/validate_5.rs | 69 |
7 files changed, 151 insertions, 349 deletions
diff --git a/src/test/mir-opt/inline-retag.rs b/src/test/mir-opt/inline-retag.rs new file mode 100644 index 00000000000..4b3280ee561 --- /dev/null +++ b/src/test/mir-opt/inline-retag.rs @@ -0,0 +1,45 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z span_free_formats -Z mir-emit-retag + +// Tests that MIR inliner fixes up `Retag`'s `fn_entry` flag + +fn main() { + println!("{}", bar()); +} + +#[inline(always)] +fn foo(x: &i32, y: &i32) -> bool { + *x == *y +} + +fn bar() -> bool { + let f = foo; + f(&1, &-1) +} + +// END RUST SOURCE +// START rustc.bar.Inline.after.mir +// ... +// bb0: { +// ... +// Retag(_3); +// Retag(_6); +// StorageLive(_9); +// _9 = (*_3); +// StorageLive(_10); +// _10 = (*_6); +// _0 = Eq(move _9, move _10); +// ... +// return; +// } +// ... +// END rustc.bar.Inline.after.mir diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs new file mode 100644 index 00000000000..9c013008ab2 --- /dev/null +++ b/src/test/mir-opt/retag.rs @@ -0,0 +1,106 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength +// compile-flags: -Z mir-emit-retag -Z mir-opt-level=0 -Z span_free_formats + +#![allow(unused)] + +struct Test(i32); + +impl Test { + // Make sure we run the pass on a method, not just on bare functions. + fn foo<'x>(&self, x: &'x mut i32) -> &'x mut i32 { x } + fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 { x } +} + +fn main() { + let mut x = 0; + { + let v = Test(0).foo(&mut x); // just making sure we do not panic when there is a tuple struct ctor + let w = { v }; // assignment + let _w = w; // reborrow + } + + // Also test closures + let c: fn(&i32) -> &i32 = |x: &i32| -> &i32 { let _y = x; x }; + let _w = c(&x); + + // need to call `foo_shr` or it doesn't even get generated + Test(0).foo_shr(&0); +} + +// END RUST SOURCE +// START rustc.{{impl}}-foo.EraseRegions.after.mir +// bb0: { +// Retag([fn entry] _1); +// Retag([fn entry] _2); +// ... +// _0 = &mut (*_3); +// ... +// return; +// } +// END rustc.{{impl}}-foo.EraseRegions.after.mir +// START rustc.{{impl}}-foo_shr.EraseRegions.after.mir +// bb0: { +// Retag([fn entry] _1); +// Retag([fn entry] _2); +// ... +// _0 = _2; +// Retag(_0); +// ... +// return; +// } +// END rustc.{{impl}}-foo_shr.EraseRegions.after.mir +// START rustc.main.EraseRegions.after.mir +// fn main() -> () { +// ... +// bb0: { +// ... +// _3 = const Test::foo(move _4, move _6) -> bb1; +// } +// +// bb1: { +// Retag(_3); +// ... +// _9 = move _3; +// Retag(_9); +// _8 = &mut (*_9); +// StorageDead(_9); +// StorageLive(_10); +// _10 = move _8; +// Retag(_10); +// ... +// _13 = move _14(move _15) -> bb2; +// } +// +// bb2: { +// Retag(_13); +// ... +// } +// ... +// } +// END rustc.main.EraseRegions.after.mir +// START rustc.main-{{closure}}.EraseRegions.after.mir +// fn main::{{closure}}(_1: &[closure@NodeId(117)], _2: &i32) -> &i32 { +// ... +// bb0: { +// Retag([fn entry] _1); +// Retag([fn entry] _2); +// StorageLive(_3); +// _3 = _2; +// Retag(_3); +// _0 = _2; +// Retag(_0); +// StorageDead(_3); +// return; +// } +// } +// END rustc.main-{{closure}}.EraseRegions.after.mir diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs deleted file mode 100644 index f1544968adb..00000000000 --- a/src/test/mir-opt/validate_1.rs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength -// compile-flags: -Z verbose -Z mir-emit-validate=1 -Z span_free_formats - -struct Test(i32); - -impl Test { - // Make sure we run the pass on a method, not just on bare functions. - fn foo(&self, _x: &mut i32) {} -} - -fn main() { - let mut x = 0; - Test(0).foo(&mut x); // just making sure we do not panic when there is a tuple struct ctor - - // Also test closures - let c = |x: &mut i32| { let y = &*x; *y }; - c(&mut x); -} - -// END RUST SOURCE -// START rustc.{{impl}}-foo.EraseRegions.after.mir -// bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/0:5 ~ validate_1[317d]::{{impl}}[0]::foo[0]), BrAnon(0)) Test, _2: &ReFree(DefId(0/0:5 ~ validate_1[317d]::{{impl}}[0]::foo[0]), BrAnon(1)) mut i32]); -// ... -// return; -// } -// END rustc.{{impl}}-foo.EraseRegions.after.mir -// START rustc.main.EraseRegions.after.mir -// fn main() -> () { -// ... -// bb0: { -// ... -// Validate(Suspend(ReScope(Node(ItemLocalId(13)))), [_1: i32]); -// _6 = &ReErased mut _1; -// Validate(Acquire, [(*_6): i32/ReScope(Node(ItemLocalId(13)))]); -// Validate(Suspend(ReScope(Node(ItemLocalId(13)))), [(*_6): i32/ReScope(Node(ItemLocalId(13)))]); -// _5 = &ReErased mut (*_6); -// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(13)))]); -// Validate(Release, [_2: (), _3: &ReScope(Node(ItemLocalId(13))) Test, _5: &ReScope(Node(ItemLocalId(13))) mut i32]); -// _2 = const Test::foo(move _3, move _5) -> bb1; -// } -// -// bb1: { -// Validate(Acquire, [_2: ()]); -// EndRegion(ReScope(Node(ItemLocalId(13)))); -// ... -// return; -// } -// } -// END rustc.main.EraseRegions.after.mir -// START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &ReErased [closure@NodeId(65)], _2: &ReErased mut i32) -> i32 { -// ... -// bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(65)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); -// StorageLive(_3); -// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(31), first_statement_index: 0 })), [(*_2): i32]); -// _3 = &ReErased (*_2); -// Validate(Acquire, [(*_3): i32/ReScope(Remainder { block: ItemLocalId(31), first_statement_index: 0 }) (imm)]); -// _0 = (*_3); -// EndRegion(ReScope(Remainder { block: ItemLocalId(31), first_statement_index: 0 })); -// StorageDead(_3); -// return; -// } -// } -// END rustc.main-{{closure}}.EraseRegions.after.mir diff --git a/src/test/mir-opt/validate_2.rs b/src/test/mir-opt/validate_2.rs deleted file mode 100644 index 3776a11b3ab..00000000000 --- a/src/test/mir-opt/validate_2.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength -// ignore-wasm32-bare unwinding being disabled causes differences in output -// ignore-wasm64-bare unwinding being disabled causes differences in output -// compile-flags: -Z verbose -Z mir-emit-validate=1 - -fn main() { - let _x : Box<[i32]> = Box::new([1, 2, 3]); -} - -// END RUST SOURCE -// START rustc.main.EraseRegions.after.mir -// fn main() -> () { -// ... -// bb1: { -// Validate(Acquire, [_2: std::boxed::Box<[i32; 3]>]); -// Validate(Release, [_2: std::boxed::Box<[i32; 3]>]); -// _1 = move _2 as std::boxed::Box<[i32]> (Unsize); -// Validate(Acquire, [_1: std::boxed::Box<[i32]>]); -// StorageDead(_2); -// StorageDead(_3); -// _0 = (); -// Validate(Release, [_1: std::boxed::Box<[i32]>]); -// drop(_1) -> [return: bb2, unwind: bb3]; -// } -// ... -// } -// END rustc.main.EraseRegions.after.mir diff --git a/src/test/mir-opt/validate_3.rs b/src/test/mir-opt/validate_3.rs deleted file mode 100644 index ce840397713..00000000000 --- a/src/test/mir-opt/validate_3.rs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength -// compile-flags: -Z verbose -Z mir-emit-validate=1 - -struct Test { - x: i32 -} - -fn foo(_x: &i32) {} - -fn main() { - // These internal unsafe functions should have no effect on the code generation. - unsafe fn _unused1() {} - fn _unused2(x: *const i32) -> i32 { unsafe { *x }} - - let t = Test { x: 0 }; - let t = &t; - foo(&t.x); -} - -// END RUST SOURCE -// START rustc.main.EraseRegions.after.mir -// fn main() -> (){ -// let mut _0: (); -// scope 1 { -// scope 3 { -// } -// scope 4 { -// let _2: &ReErased Test; -// } -// } -// scope 2 { -// let _1: Test; -// } -// let mut _3: (); -// let mut _4: &ReErased i32; -// let mut _5: &ReErased i32; -// bb0: { -// StorageLive(_1); -// _1 = Test { x: const 0i32 }; -// StorageLive(_2); -// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 })), [_1: Test]); -// _2 = &ReErased _1; -// Validate(Acquire, [(*_2): Test/ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 }) (imm)]); -// StorageLive(_4); -// StorageLive(_5); -// Validate(Suspend(ReScope(Node(ItemLocalId(22)))), [((*_2).0: i32): i32/ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 }) (imm)]); -// _5 = &ReErased ((*_2).0: i32); -// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(22))) (imm)]); -// Validate(Suspend(ReScope(Node(ItemLocalId(22)))), [(*_5): i32/ReScope(Node(ItemLocalId(22))) (imm)]); -// _4 = &ReErased (*_5); -// Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(22))) (imm)]); -// Validate(Release, [_3: (), _4: &ReScope(Node(ItemLocalId(22))) i32]); -// _3 = const foo(move _4) -> bb1; -// } -// bb1: { -// Validate(Acquire, [_3: ()]); -// EndRegion(ReScope(Node(ItemLocalId(22)))); -// StorageDead(_4); -// StorageDead(_5); -// _0 = (); -// EndRegion(ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 })); -// StorageDead(_2); -// StorageDead(_1); -// return; -// } -// } -// END rustc.main.EraseRegions.after.mir diff --git a/src/test/mir-opt/validate_4.rs b/src/test/mir-opt/validate_4.rs deleted file mode 100644 index 542ac8a4241..00000000000 --- a/src/test/mir-opt/validate_4.rs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength -// compile-flags: -Z verbose -Z mir-emit-validate=1 -Z span_free_formats - -// Make sure unsafe fns and fns with an unsafe block only get restricted validation. - -unsafe fn write_42(x: *mut i32) -> bool { - let test_closure = |x: *mut i32| *x = 23; - test_closure(x); - *x = 42; - true -} - -fn test(x: &mut i32) { - unsafe { write_42(x) }; -} - -fn main() { - test(&mut 0); - - let test_closure = unsafe { |x: &mut i32| write_42(x) }; - test_closure(&mut 0); -} - -// FIXME: Also test code generated inside the closure, make sure it only does restricted validation -// because it is entirely inside an unsafe block. Unfortunately, the interesting lines of code also -// contain name of the source file, so we cannot test for it. - -// END RUST SOURCE -// START rustc.write_42.EraseRegions.after.mir -// fn write_42(_1: *mut i32) -> bool { -// ... -// bb0: { -// Validate(Acquire, [_1: *mut i32]); -// Validate(Release, [_1: *mut i32]); -// ... -// return; -// } -// } -// END rustc.write_42.EraseRegions.after.mir -// START rustc.write_42-{{closure}}.EraseRegions.after.mir -// fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(32)], _2: *mut i32) -> () { -// ... -// bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(32)], _2: *mut i32]); -// Validate(Release, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(32)], _2: *mut i32]); -// (*_2) = const 23i32; -// _0 = (); -// return; -// } -// } -// END rustc.write_42-{{closure}}.EraseRegions.after.mir -// START rustc.test.EraseRegions.after.mir -// fn test(_1: &ReErased mut i32) -> () { -// ... -// bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/0:4 ~ validate_4[317d]::test[0]), BrAnon(0)) mut i32]); -// Validate(Release, [_1: &ReFree(DefId(0/0:4 ~ validate_4[317d]::test[0]), BrAnon(0)) mut i32]); -// ... -// _2 = const write_42(move _3) -> bb1; -// } -// bb1: { -// Validate(Acquire, [_2: bool]); -// Validate(Release, [_2: bool]); -// ... -// } -// } -// END rustc.test.EraseRegions.after.mir -// START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &ReErased [closure@NodeId(80)], _2: &ReErased mut i32) -> bool { -// ... -// bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(80)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); -// Validate(Release, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(80)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); -// StorageLive(_3); -// ... -// _0 = const write_42(move _3) -> bb1; -// } -// ... -// } -// END rustc.main-{{closure}}.EraseRegions.after.mir diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs deleted file mode 100644 index 955de0c3bad..00000000000 --- a/src/test/mir-opt/validate_5.rs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-tidy-linelength -// compile-flags: -Z verbose -Z mir-emit-validate=2 -Z span_free_formats - -// Make sure unsafe fns and fns with an unsafe block still get full validation. - -unsafe fn write_42(x: *mut i32) -> bool { - *x = 42; - true -} - -fn test(x: &mut i32) { - unsafe { write_42(x) }; -} - -fn main() { - test(&mut 0); - - let test_closure = unsafe { |x: &mut i32| write_42(x) }; - // Note that validation will fail if this is executed: The closure keeps the lock on - // x, so the write in write_42 fails. This test just checks code generation, - // so the UB doesn't matter. - test_closure(&mut 0); -} - -// END RUST SOURCE -// START rustc.test.EraseRegions.after.mir -// fn test(_1: &ReErased mut i32) -> () { -// ... -// bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/0:4 ~ validate_5[317d]::test[0]), BrAnon(0)) mut i32]); -// ... -// Validate(Release, [_2: bool, _3: *mut i32]); -// _2 = const write_42(move _3) -> bb1; -// } -// ... -// } -// END rustc.test.EraseRegions.after.mir -// START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &ReErased [closure@NodeId(62)], _2: &ReErased mut i32) -> bool { -// ... -// bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(62)], _2: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); -// StorageLive(_3); -// StorageLive(_4); -// StorageLive(_5); -// Validate(Suspend(ReScope(Node(ItemLocalId(16)))), [(*_2): i32]); -// _5 = &ReErased mut (*_2); -// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(16)))]); -// _4 = move _5 as *mut i32 (Misc); -// _3 = move _4; -// EndRegion(ReScope(Node(ItemLocalId(16)))); -// StorageDead(_4); -// StorageDead(_5); -// Validate(Release, [_0: bool, _3: *mut i32]); -// _0 = const write_42(move _3) -> bb1; -// } -// ... -// } -// END rustc.main-{{closure}}.EraseRegions.after.mir |
