parent
de7cb0fdd6
commit
a091cfd4f3
10 changed files with 1431 additions and 2 deletions
44
src/test/run-fail/issue-30380.rs
Normal file
44
src/test/run-fail/issue-30380.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// 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.
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
100
src/test/run-pass/dynamic-drop.rs
Normal file
100
src/test/run-pass/dynamic-drop.rs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// 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.
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
struct Allocator {
|
||||
data: RefCell<Vec<bool>>,
|
||||
}
|
||||
|
||||
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() -> Self { Allocator { data: RefCell::new(vec![]) } }
|
||||
fn alloc(&self) -> Ptr {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn dynamic_init(a: &Allocator, c: bool) {
|
||||
let _x;
|
||||
if c {
|
||||
_x = Some(a.alloc());
|
||||
}
|
||||
}
|
||||
|
||||
fn dynamic_drop(a: &Allocator, c: bool) -> Option<Ptr> {
|
||||
let x = a.alloc();
|
||||
if c {
|
||||
Some(x)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
fn assignment1(a: &Allocator, c0: bool) {
|
||||
let mut _v = a.alloc();
|
||||
let mut _w = a.alloc();
|
||||
if c0 {
|
||||
drop(_v);
|
||||
}
|
||||
_v = _w;
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
let a = Allocator::new();
|
||||
dynamic_init(&a, false);
|
||||
dynamic_init(&a, true);
|
||||
dynamic_drop(&a, false);
|
||||
dynamic_drop(&a, true);
|
||||
|
||||
assignment2(&a, false, false);
|
||||
assignment2(&a, false, true);
|
||||
assignment2(&a, true, false);
|
||||
assignment2(&a, true, true);
|
||||
|
||||
assignment1(&a, false);
|
||||
assignment1(&a, true);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue