Skip to content

Commit df1283c

Browse files
committed
Unit/regression tests for issues #29092, #30018, #30530, #30822.
Note that the test for #30822 is folded into the test for #30530 (but the file name mentions only 30530).
1 parent f251ff4 commit df1283c

File tree

4 files changed

+213
-0
lines changed

4 files changed

+213
-0
lines changed

src/test/run-pass/issue-29092.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2012-2016 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+
// Regression test for Issue #29092.
12+
//
13+
// (Possibly redundant with regression test run-pass/issue-30530.rs)
14+
15+
use self::Term::*;
16+
17+
#[derive(Clone)]
18+
pub enum Term {
19+
Dummy,
20+
A(Box<Term>),
21+
B(Box<Term>),
22+
}
23+
24+
// a small-step evaluator
25+
pub fn small_eval(v: Term) -> Term {
26+
match v {
27+
A(t) => *t.clone(),
28+
B(t) => *t.clone(),
29+
_ => Dummy,
30+
}
31+
}
32+
33+
fn main() {
34+
small_eval(Dummy);
35+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// Copyright 2012-2016 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+
// More thorough regression test for Issues #30018 and #30822. This
12+
// attempts to explore different ways that array element construction
13+
// (for both scratch arrays and non-scratch ones) interacts with
14+
// breaks in the control-flow, in terms of the order of evaluation of
15+
// the destructors (which may change; see RFC Issue 744) and the
16+
// number of times that the destructor evaluates for each value (which
17+
// should never exceed 1; this latter case is what #30822 is about).
18+
19+
use std::cell::RefCell;
20+
21+
struct D<'a>(&'a RefCell<Vec<i32>>, i32);
22+
23+
impl<'a> Drop for D<'a> {
24+
fn drop(&mut self) {
25+
println!("Dropping D({})", self.1);
26+
(self.0).borrow_mut().push(self.1);
27+
}
28+
}
29+
30+
fn main() {
31+
println!("Start");
32+
break_during_elem();
33+
break_after_whole();
34+
println!("Finis");
35+
}
36+
37+
fn break_during_elem() {
38+
let log = &RefCell::new(Vec::new());
39+
40+
// CASE 1: Fixed-size array itself is stored in _r slot.
41+
loop {
42+
let _r = [D(log, 10),
43+
D(log, 11),
44+
{ D(log, 12); break; },
45+
D(log, 13)];
46+
}
47+
assert_eq!(&log.borrow()[..], &[12, 11, 10]);
48+
log.borrow_mut().clear();
49+
50+
// CASE 2: Slice (borrow of array) is stored in _r slot.
51+
// This is the case that is actually being reported in #30018.
52+
loop {
53+
let _r = &[D(log, 20),
54+
D(log, 21),
55+
{ D(log, 22); break; },
56+
D(log, 23)];
57+
}
58+
assert_eq!(&log.borrow()[..], &[22, 21, 20]);
59+
log.borrow_mut().clear();
60+
61+
// CASE 3: (Borrow of) slice-index of array is stored in _r slot.
62+
loop {
63+
let _r = &[D(log, 30),
64+
D(log, 31),
65+
{ D(log, 32); break; },
66+
D(log, 33)][..];
67+
}
68+
assert_eq!(&log.borrow()[..], &[32, 31, 30]);
69+
log.borrow_mut().clear();
70+
}
71+
72+
// The purpose of these functions is to test what happens when we
73+
// panic after an array has been constructed in its entirety.
74+
//
75+
// It is meant to act as proof that we still need to continue
76+
// scheduling the destruction of an array even after we've scheduling
77+
// drop for its elements during construction; the latter is tested by
78+
// `fn break_during_elem()`.
79+
fn break_after_whole() {
80+
let log = &RefCell::new(Vec::new());
81+
82+
// CASE 1: Fixed-size array itself is stored in _r slot.
83+
loop {
84+
let _r = [D(log, 10),
85+
D(log, 11),
86+
D(log, 12)];
87+
break;
88+
}
89+
assert_eq!(&log.borrow()[..], &[10, 11, 12]);
90+
log.borrow_mut().clear();
91+
92+
// CASE 2: Slice (borrow of array) is stored in _r slot.
93+
loop {
94+
let _r = &[D(log, 20),
95+
D(log, 21),
96+
D(log, 22)];
97+
break;
98+
}
99+
assert_eq!(&log.borrow()[..], &[20, 21, 22]);
100+
log.borrow_mut().clear();
101+
102+
// CASE 3: (Borrow of) slice-index of array is stored in _r slot.
103+
loop {
104+
let _r = &[D(log, 30),
105+
D(log, 31),
106+
D(log, 32)][..];
107+
break;
108+
}
109+
assert_eq!(&log.borrow()[..], &[30, 31, 32]);
110+
log.borrow_mut().clear();
111+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2012-2016 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+
// Regression test for Issue #30018. This is very similar to the
12+
// original reported test, except that the panic is wrapped in a
13+
// spawned thread to isolate the expected error result from the
14+
// SIGTRAP injected by the drop-flag consistency checking.
15+
16+
struct Foo;
17+
18+
impl Drop for Foo {
19+
fn drop(&mut self) {}
20+
}
21+
22+
fn foo() -> Foo {
23+
panic!();
24+
}
25+
26+
fn main() {
27+
use std::thread;
28+
let handle = thread::spawn(|| {
29+
let _ = &[foo()];
30+
});
31+
let _ = handle.join();
32+
}

src/test/run-pass/issue-30530.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2012-2016 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+
// Regression test for Issue #30530: alloca's created for storing
12+
// intermediate scratch values during brace-less match arms need to be
13+
// initialized with their drop-flag set to "dropped" (or else we end
14+
// up running the destructors on garbage data at the end of the
15+
// function).
16+
17+
pub enum Handler {
18+
Default,
19+
#[allow(dead_code)]
20+
Custom(*mut Box<Fn()>),
21+
}
22+
23+
fn main() {
24+
take(Handler::Default, Box::new(main));
25+
}
26+
27+
#[inline(never)]
28+
pub fn take(h: Handler, f: Box<Fn()>) -> Box<Fn()> {
29+
unsafe {
30+
match h {
31+
Handler::Custom(ptr) => *Box::from_raw(ptr),
32+
Handler::Default => f,
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)