diff options
| author | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-05-23 11:21:01 +0200 |
|---|---|---|
| committer | Felix S. Klock II <pnkfelix@pnkfx.org> | 2018-05-29 23:02:40 +0200 |
| commit | 9d5cdc958db3ee832dbdb781358442fddd51d6ee (patch) | |
| tree | 3f41f60e40a849321c799147c40d9b3d14ee040f /src | |
| parent | 324ced89e89a4e050ab2d0ef9e30e4ec8968f51a (diff) | |
| download | rust-9d5cdc958db3ee832dbdb781358442fddd51d6ee.tar.gz rust-9d5cdc958db3ee832dbdb781358442fddd51d6ee.zip | |
Review feedback: Adding test cases suggested by arielb1.
Diffstat (limited to 'src')
4 files changed, 146 insertions, 0 deletions
diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.rs b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.rs new file mode 100644 index 00000000000..b575f4ebce6 --- /dev/null +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.rs @@ -0,0 +1,43 @@ +// Copyright 2018 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. + +// This is testing an attempt to corrupt the discriminant of the match +// arm in a guard, followed by an attempt to continue matching on that +// corrupted discriminant in the remaining match arms. +// +// Basically this is testing that our new NLL feature of emitting a +// fake read on each match arm is catching cases like this. +// +// This case is interesting because it includes a guard that +// diverges, and therefore a single final fake-read at the very end +// after the final match arm would not suffice. + +#![feature(nll)] + +struct ForceFnOnce; + +fn main() { + let mut x = &mut Some(&2); + let force_fn_once = ForceFnOnce; + match x { + &mut None => panic!("unreachable"), + &mut Some(&_) if { + // ForceFnOnce needed to exploit #27282 + (|| { *x = None; drop(force_fn_once); })(); + //~^ ERROR closure requires unique access to `x` but it is already borrowed [E0500] + false + } => {} + &mut Some(&a) if { // this binds to garbage if we've corrupted discriminant + println!("{}", a); + panic!() + } => {} + _ => panic!("unreachable"), + } +} diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr new file mode 100644 index 00000000000..8f7fe9d33fe --- /dev/null +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr @@ -0,0 +1,25 @@ +error[E0500]: closure requires unique access to `x` but it is already borrowed + --> $DIR/issue-27282-mutate-before-diverging-arm-1.rs:33:14 + | +LL | match x { + | _____- + | |_____| + | || +LL | || &mut None => panic!("unreachable"), +LL | || &mut Some(&_) if { +LL | || // ForceFnOnce needed to exploit #27282 +LL | || (|| { *x = None; drop(force_fn_once); })(); + | || ^^ - borrow occurs due to use of `x` in closure + | || | + | || closure construction occurs here +... || +LL | || _ => panic!("unreachable"), +LL | || } + | || - + | ||_____| + | |______borrow occurs here + | borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0500`. diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.rs b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.rs new file mode 100644 index 00000000000..866fed13685 --- /dev/null +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.rs @@ -0,0 +1,52 @@ +// Copyright 2018 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. + +// This is testing an attempt to corrupt the discriminant of the match +// arm in a guard, followed by an attempt to continue matching on that +// corrupted discriminant in the remaining match arms. +// +// Basically this is testing that our new NLL feature of emitting a +// fake read on each match arm is catching cases like this. +// +// This case is interesting because it includes a guard that +// diverges, and therefore a single final fake-read at the very end +// after the final match arm would not suffice. +// +// It is also interesting because the access to the corrupted data +// occurs in the pattern-match itself, and not in the guard +// expression. + +#![feature(nll)] + +struct ForceFnOnce; + +fn main() { + let mut x = &mut Some(&2); + let force_fn_once = ForceFnOnce; + match x { + &mut None => panic!("unreachable"), + &mut Some(&_) + if { + // ForceFnOnce needed to exploit #27282 + (|| { *x = None; drop(force_fn_once); })(); + //~^ ERROR closure requires unique access to `x` but it is already borrowed [E0500] + false + } => {} + + // this segfaults if we corrupted the discriminant, because + // the compiler gets to *assume* that it cannot be the `None` + // case, even though that was the effect of the guard. + &mut Some(&2) + if { + panic!() + } => {} + _ => panic!("unreachable"), + } +} diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr new file mode 100644 index 00000000000..df5e4300cec --- /dev/null +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr @@ -0,0 +1,26 @@ +error[E0500]: closure requires unique access to `x` but it is already borrowed + --> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:38:18 + | +LL | match x { + | _____- + | |_____| + | || +LL | || &mut None => panic!("unreachable"), +LL | || &mut Some(&_) +LL | || if { +LL | || // ForceFnOnce needed to exploit #27282 +LL | || (|| { *x = None; drop(force_fn_once); })(); + | || ^^ - borrow occurs due to use of `x` in closure + | || | + | || closure construction occurs here +... || +LL | || _ => panic!("unreachable"), +LL | || } + | || - + | ||_____| + | |______borrow occurs here + | borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0500`. |
