diff options
| author | bors <bors@rust-lang.org> | 2016-06-04 23:49:29 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-06-04 23:49:29 -0700 |
| commit | f97c411548f2b64f74f2bcb84dcc37075c05e2a0 (patch) | |
| tree | 78f88d09614f89ea7e955252407bc0da5f02332b /src/test | |
| parent | ccfaaa7d989356ff440e9960da28909491e2f00d (diff) | |
| parent | 063f8826e7addbe644e3dfd532736ce72d8990bc (diff) | |
| download | rust-f97c411548f2b64f74f2bcb84dcc37075c05e2a0.tar.gz rust-f97c411548f2b64f74f2bcb84dcc37075c05e2a0.zip | |
Auto merge of #33622 - arielb1:elaborate-drops, r=nikomatsakis
[MIR] non-zeroing drop This enables non-zeroing drop through stack flags for MIR. Fixes #30380. Fixes #5016.
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/codegen-units/item-collection/cross-crate-trait-method.rs | 2 | ||||
| -rw-r--r-- | src/test/codegen-units/item-collection/generic-functions.rs | 2 | ||||
| -rw-r--r-- | src/test/codegen-units/partitioning/local-generic.rs | 2 | ||||
| -rw-r--r-- | src/test/run-fail/issue-30380.rs | 47 | ||||
| -rw-r--r-- | src/test/run-make/atomic-lock-free/atomic_lock_free.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/dynamic-drop.rs | 156 |
6 files changed, 205 insertions, 6 deletions
diff --git a/src/test/codegen-units/item-collection/cross-crate-trait-method.rs b/src/test/codegen-units/item-collection/cross-crate-trait-method.rs index 9f29a90bffb..195125793be 100644 --- a/src/test/codegen-units/item-collection/cross-crate-trait-method.rs +++ b/src/test/codegen-units/item-collection/cross-crate-trait-method.rs @@ -56,5 +56,3 @@ fn main() //~ TRANS_ITEM fn cgu_export_trait_method::{{impl}}[0]::without_default_impl_generic[0]<bool> let _: (char, bool) = Trait::without_default_impl_generic(false); } - -//~ TRANS_ITEM drop-glue i8 diff --git a/src/test/codegen-units/item-collection/generic-functions.rs b/src/test/codegen-units/item-collection/generic-functions.rs index 5ec1f7fbc3c..afe6ffc8bfe 100644 --- a/src/test/codegen-units/item-collection/generic-functions.rs +++ b/src/test/codegen-units/item-collection/generic-functions.rs @@ -60,5 +60,3 @@ fn main() { //~ TRANS_ITEM fn generic_functions::foo3[0]<char, (), ()> let _ = foo3('v', (), ()); } - -//~ TRANS_ITEM drop-glue i8 diff --git a/src/test/codegen-units/partitioning/local-generic.rs b/src/test/codegen-units/partitioning/local-generic.rs index e38e676b95c..f5641f1f2ed 100644 --- a/src/test/codegen-units/partitioning/local-generic.rs +++ b/src/test/codegen-units/partitioning/local-generic.rs @@ -56,5 +56,3 @@ mod mod2 { let _ = generic("abc"); } } - -//~ TRANS_ITEM drop-glue i8 diff --git a/src/test/run-fail/issue-30380.rs b/src/test/run-fail/issue-30380.rs new file mode 100644 index 00000000000..eb668517bdf --- /dev/null +++ b/src/test/run-fail/issue-30380.rs @@ -0,0 +1,47 @@ +// Copyright 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. + +#![feature(rustc_attrs)] + +// check that panics in destructors during assignment do not leave +// destroyed values lying around for other destructors to observe. + +// error-pattern:panicking destructors ftw! + +struct Observer<'a>(&'a mut FilledOnDrop); + +struct FilledOnDrop(u32); +impl Drop for FilledOnDrop { + fn drop(&mut self) { + if self.0 == 0 { + // this is only set during the destructor - safe + // code should not be able to observe this. + self.0 = 0x1c1c1c1c; + panic!("panicking destructors ftw!"); + } + } +} + +impl<'a> Drop for Observer<'a> { + fn drop(&mut self) { + assert_eq!(self.0 .0, 1); + } +} + +#[rustc_mir] +fn foo(b: &mut Observer) { + *b.0 = FilledOnDrop(1); +} + +fn main() { + let mut bomb = FilledOnDrop(0); + let mut observer = Observer(&mut bomb); + foo(&mut observer); +} diff --git a/src/test/run-make/atomic-lock-free/atomic_lock_free.rs b/src/test/run-make/atomic-lock-free/atomic_lock_free.rs index 8731cd960f3..023f2218b87 100644 --- a/src/test/run-make/atomic-lock-free/atomic_lock_free.rs +++ b/src/test/run-make/atomic-lock-free/atomic_lock_free.rs @@ -18,6 +18,8 @@ extern "rust-intrinsic" { #[lang = "sized"] trait Sized {} +#[lang = "copy"] +trait Copy {} #[cfg(target_has_atomic = "8")] pub unsafe fn atomic_u8(x: *mut u8) { diff --git a/src/test/run-pass/dynamic-drop.rs b/src/test/run-pass/dynamic-drop.rs new file mode 100644 index 00000000000..f917531e868 --- /dev/null +++ b/src/test/run-pass/dynamic-drop.rs @@ -0,0 +1,156 @@ +// Copyright 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. + +#![feature(rustc_attrs)] + +use std::cell::{Cell, RefCell}; +use std::panic; +use std::usize; + +struct InjectedFailure; + +struct Allocator { + data: RefCell<Vec<bool>>, + failing_op: usize, + cur_ops: Cell<usize>, +} + +impl panic::UnwindSafe for Allocator {} +impl panic::RefUnwindSafe for Allocator {} + +impl Drop for Allocator { + fn drop(&mut self) { + let data = self.data.borrow(); + if data.iter().any(|d| *d) { + panic!("missing free: {:?}", data); + } + } +} + +impl Allocator { + fn new(failing_op: usize) -> Self { + Allocator { + failing_op: failing_op, + cur_ops: Cell::new(0), + data: RefCell::new(vec![]) + } + } + fn alloc(&self) -> Ptr { + self.cur_ops.set(self.cur_ops.get() + 1); + + if self.cur_ops.get() == self.failing_op { + panic!(InjectedFailure); + } + + let mut data = self.data.borrow_mut(); + let addr = data.len(); + data.push(true); + Ptr(addr, self) + } +} + +struct Ptr<'a>(usize, &'a Allocator); +impl<'a> Drop for Ptr<'a> { + fn drop(&mut self) { + match self.1.data.borrow_mut()[self.0] { + false => { + panic!("double free at index {:?}", self.0) + } + ref mut d => *d = false + } + + self.1.cur_ops.set(self.1.cur_ops.get()+1); + + if self.1.cur_ops.get() == self.1.failing_op { + panic!(InjectedFailure); + } + } +} + +#[rustc_mir] +fn dynamic_init(a: &Allocator, c: bool) { + let _x; + if c { + _x = Some(a.alloc()); + } +} + +#[rustc_mir] +fn dynamic_drop(a: &Allocator, c: bool) { + let x = a.alloc(); + if c { + Some(x) + } else { + None + }; +} + +#[rustc_mir] +fn assignment2(a: &Allocator, c0: bool, c1: bool) { + let mut _v = a.alloc(); + let mut _w = a.alloc(); + if c0 { + drop(_v); + } + _v = _w; + if c1 { + _w = a.alloc(); + } +} + +#[rustc_mir] +fn assignment1(a: &Allocator, c0: bool) { + let mut _v = a.alloc(); + let mut _w = a.alloc(); + if c0 { + drop(_v); + } + _v = _w; +} + +fn run_test<F>(mut f: F) + where F: FnMut(&Allocator) +{ + let first_alloc = Allocator::new(usize::MAX); + f(&first_alloc); + + for failing_op in 1..first_alloc.cur_ops.get()+1 { + let alloc = Allocator::new(failing_op); + let alloc = &alloc; + let f = panic::AssertUnwindSafe(&mut f); + let result = panic::catch_unwind(move || { + f.0(alloc); + }); + match result { + Ok(..) => panic!("test executed {} ops but now {}", + first_alloc.cur_ops.get(), alloc.cur_ops.get()), + Err(e) => { + if e.downcast_ref::<InjectedFailure>().is_none() { + panic::resume_unwind(e); + } + } + } + } +} + +fn main() { + run_test(|a| dynamic_init(a, false)); + run_test(|a| dynamic_init(a, true)); + run_test(|a| dynamic_drop(a, false)); + run_test(|a| dynamic_drop(a, true)); + + run_test(|a| assignment2(a, false, false)); + run_test(|a| assignment2(a, false, true)); + run_test(|a| assignment2(a, true, false)); + run_test(|a| assignment2(a, true, true)); + + run_test(|a| assignment1(a, false)); + run_test(|a| assignment1(a, true)); +} |
