]> git.lizzy.rs Git - rust.git/commitdiff
Unit/regression tests for issues #29092, #30018, #30530, #30822.
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Mon, 11 Jan 2016 17:32:28 +0000 (18:32 +0100)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Wed, 13 Jan 2016 13:29:25 +0000 (14:29 +0100)
Note that the test for #30822 is folded into the test for #30530 (but
the file name mentions only 30530).

src/test/run-pass/issue-29092.rs [new file with mode: 0644]
src/test/run-pass/issue-30018-nopanic.rs [new file with mode: 0644]
src/test/run-pass/issue-30018-panic.rs [new file with mode: 0644]
src/test/run-pass/issue-30530.rs [new file with mode: 0644]

diff --git a/src/test/run-pass/issue-29092.rs b/src/test/run-pass/issue-29092.rs
new file mode 100644 (file)
index 0000000..c55cc91
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2012-2016 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.
+
+// Regression test for Issue #29092.
+//
+// (Possibly redundant with regression test run-pass/issue-30530.rs)
+
+use self::Term::*;
+
+#[derive(Clone)]
+pub enum Term {
+    Dummy,
+    A(Box<Term>),
+    B(Box<Term>),
+}
+
+// a small-step evaluator
+pub fn small_eval(v: Term) -> Term {
+    match v {
+        A(t) => *t.clone(),
+        B(t) => *t.clone(),
+        _ => Dummy,
+    }
+}
+
+fn main() {
+    small_eval(Dummy);
+}
diff --git a/src/test/run-pass/issue-30018-nopanic.rs b/src/test/run-pass/issue-30018-nopanic.rs
new file mode 100644 (file)
index 0000000..25eff9d
--- /dev/null
@@ -0,0 +1,111 @@
+// Copyright 2012-2016 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.
+
+// More thorough regression test for Issues #30018 and #30822. This
+// attempts to explore different ways that array element construction
+// (for both scratch arrays and non-scratch ones) interacts with
+// breaks in the control-flow, in terms of the order of evaluation of
+// the destructors (which may change; see RFC Issue 744) and the
+// number of times that the destructor evaluates for each value (which
+// should never exceed 1; this latter case is what #30822 is about).
+
+use std::cell::RefCell;
+
+struct D<'a>(&'a RefCell<Vec<i32>>, i32);
+
+impl<'a> Drop for D<'a> {
+    fn drop(&mut self) {
+        println!("Dropping D({})", self.1);
+        (self.0).borrow_mut().push(self.1);
+    }
+}
+
+fn main() {
+    println!("Start");
+    break_during_elem();
+    break_after_whole();
+    println!("Finis");
+}
+
+fn break_during_elem() {
+    let log = &RefCell::new(Vec::new());
+
+    // CASE 1: Fixed-size array itself is stored in _r slot.
+    loop {
+        let _r = [D(log, 10),
+                  D(log, 11),
+                  { D(log, 12); break; },
+                  D(log, 13)];
+    }
+    assert_eq!(&log.borrow()[..], &[12, 11, 10]);
+    log.borrow_mut().clear();
+
+    // CASE 2: Slice (borrow of array) is stored in _r slot.
+    // This is the case that is actually being reported in #30018.
+    loop {
+        let _r = &[D(log, 20),
+                   D(log, 21),
+                   { D(log, 22); break; },
+                   D(log, 23)];
+    }
+    assert_eq!(&log.borrow()[..], &[22, 21, 20]);
+    log.borrow_mut().clear();
+
+    // CASE 3: (Borrow of) slice-index of array is stored in _r slot.
+    loop {
+        let _r = &[D(log, 30),
+                  D(log, 31),
+                  { D(log, 32); break; },
+                  D(log, 33)][..];
+    }
+    assert_eq!(&log.borrow()[..], &[32, 31, 30]);
+    log.borrow_mut().clear();
+}
+
+// The purpose of these functions is to test what happens when we
+// panic after an array has been constructed in its entirety.
+//
+// It is meant to act as proof that we still need to continue
+// scheduling the destruction of an array even after we've scheduling
+// drop for its elements during construction; the latter is tested by
+// `fn break_during_elem()`.
+fn break_after_whole() {
+    let log = &RefCell::new(Vec::new());
+
+    // CASE 1: Fixed-size array itself is stored in _r slot.
+    loop {
+        let _r = [D(log, 10),
+                  D(log, 11),
+                  D(log, 12)];
+        break;
+    }
+    assert_eq!(&log.borrow()[..], &[10, 11, 12]);
+    log.borrow_mut().clear();
+
+    // CASE 2: Slice (borrow of array) is stored in _r slot.
+    loop {
+        let _r = &[D(log, 20),
+                   D(log, 21),
+                   D(log, 22)];
+        break;
+    }
+    assert_eq!(&log.borrow()[..], &[20, 21, 22]);
+    log.borrow_mut().clear();
+
+    // CASE 3: (Borrow of) slice-index of array is stored in _r slot.
+    loop {
+        let _r = &[D(log, 30),
+                   D(log, 31),
+                   D(log, 32)][..];
+        break;
+    }
+    assert_eq!(&log.borrow()[..], &[30, 31, 32]);
+    log.borrow_mut().clear();
+}
diff --git a/src/test/run-pass/issue-30018-panic.rs b/src/test/run-pass/issue-30018-panic.rs
new file mode 100644 (file)
index 0000000..da4d5f1
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2012-2016 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.
+
+// Regression test for Issue #30018. This is very similar to the
+// original reported test, except that the panic is wrapped in a
+// spawned thread to isolate the expected error result from the
+// SIGTRAP injected by the drop-flag consistency checking.
+
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+fn foo() -> Foo {
+    panic!();
+}
+
+fn main() {
+    use std::thread;
+    let handle = thread::spawn(|| {
+        let _ = &[foo()];
+    });
+    let _ = handle.join();
+}
diff --git a/src/test/run-pass/issue-30530.rs b/src/test/run-pass/issue-30530.rs
new file mode 100644 (file)
index 0000000..d5139c9
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright 2012-2016 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.
+
+// Regression test for Issue #30530: alloca's created for storing
+// intermediate scratch values during brace-less match arms need to be
+// initialized with their drop-flag set to "dropped" (or else we end
+// up running the destructors on garbage data at the end of the
+// function).
+
+pub enum Handler {
+    Default,
+    #[allow(dead_code)]
+    Custom(*mut Box<Fn()>),
+}
+
+fn main() {
+    take(Handler::Default, Box::new(main));
+}
+
+#[inline(never)]
+pub fn take(h: Handler, f: Box<Fn()>) -> Box<Fn()> {
+    unsafe {
+        match h {
+            Handler::Custom(ptr) => *Box::from_raw(ptr),
+            Handler::Default => f,
+        }
+    }
+}