summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2018-05-23 11:21:01 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2018-05-29 23:02:40 +0200
commit9d5cdc958db3ee832dbdb781358442fddd51d6ee (patch)
tree3f41f60e40a849321c799147c40d9b3d14ee040f
parentReview feedback: Fix typo. (diff)
downloadgrust-9d5cdc958db3ee832dbdb781358442fddd51d6ee.tar.gz
grust-9d5cdc958db3ee832dbdb781358442fddd51d6ee.tar.bz2
grust-9d5cdc958db3ee832dbdb781358442fddd51d6ee.tar.xz
Review feedback: Adding test cases suggested by arielb1.
-rw-r--r--src/test/ui/issue-27282-mutate-before-diverging-arm-1.rs43
-rw-r--r--src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr25
-rw-r--r--src/test/ui/issue-27282-mutate-before-diverging-arm-2.rs52
-rw-r--r--src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr26
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 0000000000..b575f4ebce
--- /dev/null
+++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.rs
@@ -0,0 +1,43 @@
1// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11// This is testing an attempt to corrupt the discriminant of the match
12// arm in a guard, followed by an attempt to continue matching on that
13// corrupted discriminant in the remaining match arms.
14//
15// Basically this is testing that our new NLL feature of emitting a
16// fake read on each match arm is catching cases like this.
17//
18// This case is interesting because it includes a guard that
19// diverges, and therefore a single final fake-read at the very end
20// after the final match arm would not suffice.
21
22#![feature(nll)]
23
24struct ForceFnOnce;
25
26fn main() {
27 let mut x = &mut Some(&2);
28 let force_fn_once = ForceFnOnce;
29 match x {
30 &mut None => panic!("unreachable"),
31 &mut Some(&_) if {
32 // ForceFnOnce needed to exploit #27282
33 (|| { *x = None; drop(force_fn_once); })();
34 //~^ ERROR closure requires unique access to `x` but it is already borrowed [E0500]
35 false
36 } => {}
37 &mut Some(&a) if { // this binds to garbage if we've corrupted discriminant
38 println!("{}", a);
39 panic!()
40 } => {}
41 _ => panic!("unreachable"),
42 }
43}
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 0000000000..8f7fe9d33f
--- /dev/null
+++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr
@@ -0,0 +1,25 @@
1error[E0500]: closure requires unique access to `x` but it is already borrowed
2 --> $DIR/issue-27282-mutate-before-diverging-arm-1.rs:33:14
3 |
4LL | match x {
5 | _____-
6 | |_____|
7 | ||
8LL | || &mut None => panic!("unreachable"),
9LL | || &mut Some(&_) if {
10LL | || // ForceFnOnce needed to exploit #27282
11LL | || (|| { *x = None; drop(force_fn_once); })();
12 | || ^^ - borrow occurs due to use of `x` in closure
13 | || |
14 | || closure construction occurs here
15... ||
16LL | || _ => panic!("unreachable"),
17LL | || }
18 | || -
19 | ||_____|
20 | |______borrow occurs here
21 | borrow later used here
22
23error: aborting due to previous error
24
25For 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 0000000000..866fed1368
--- /dev/null
+++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.rs
@@ -0,0 +1,52 @@
1// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11// This is testing an attempt to corrupt the discriminant of the match
12// arm in a guard, followed by an attempt to continue matching on that
13// corrupted discriminant in the remaining match arms.
14//
15// Basically this is testing that our new NLL feature of emitting a
16// fake read on each match arm is catching cases like this.
17//
18// This case is interesting because it includes a guard that
19// diverges, and therefore a single final fake-read at the very end
20// after the final match arm would not suffice.
21//
22// It is also interesting because the access to the corrupted data
23// occurs in the pattern-match itself, and not in the guard
24// expression.
25
26#![feature(nll)]
27
28struct ForceFnOnce;
29
30fn main() {
31 let mut x = &mut Some(&2);
32 let force_fn_once = ForceFnOnce;
33 match x {
34 &mut None => panic!("unreachable"),
35 &mut Some(&_)
36 if {
37 // ForceFnOnce needed to exploit #27282
38 (|| { *x = None; drop(force_fn_once); })();
39 //~^ ERROR closure requires unique access to `x` but it is already borrowed [E0500]
40 false
41 } => {}
42
43 // this segfaults if we corrupted the discriminant, because
44 // the compiler gets to *assume* that it cannot be the `None`
45 // case, even though that was the effect of the guard.
46 &mut Some(&2)
47 if {
48 panic!()
49 } => {}
50 _ => panic!("unreachable"),
51 }
52}
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 0000000000..df5e4300ce
--- /dev/null
+++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr
@@ -0,0 +1,26 @@
1error[E0500]: closure requires unique access to `x` but it is already borrowed
2 --> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:38:18
3 |
4LL | match x {
5 | _____-
6 | |_____|
7 | ||
8LL | || &mut None => panic!("unreachable"),
9LL | || &mut Some(&_)
10LL | || if {
11LL | || // ForceFnOnce needed to exploit #27282
12LL | || (|| { *x = None; drop(force_fn_once); })();
13 | || ^^ - borrow occurs due to use of `x` in closure
14 | || |
15 | || closure construction occurs here
16... ||
17LL | || _ => panic!("unreachable"),
18LL | || }
19 | || -
20 | ||_____|
21 | |______borrow occurs here
22 | borrow later used here
23
24error: aborting due to previous error
25
26For more information about this error, try `rustc --explain E0500`.