From aab4bef9394daf84690474694b5a14587664be80 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 25 Mar 2015 16:49:21 +0100 Subject: [PATCH] Add tests exercising the dropflag checking functionality. --- src/test/run-pass/drop-flag-sanity-check.rs | 67 +++++++++++++++++++ .../run-pass/drop-flag-skip-sanity-check.rs | 67 +++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 src/test/run-pass/drop-flag-sanity-check.rs create mode 100644 src/test/run-pass/drop-flag-skip-sanity-check.rs diff --git a/src/test/run-pass/drop-flag-sanity-check.rs b/src/test/run-pass/drop-flag-sanity-check.rs new file mode 100644 index 00000000000..bc836f6c848 --- /dev/null +++ b/src/test/run-pass/drop-flag-sanity-check.rs @@ -0,0 +1,67 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z force-dropflag-checks=on + +// Quick-and-dirty test to ensure -Z force-dropflag-checks=on works as +// expected. Note that the inlined drop-flag is slated for removal +// (RFC 320); when that happens, the -Z flag and this test should +// simply be removed. +// +// See also drop-flag-skip-sanity-check.rs. + +use std::env; +use std::old_io::process::{Command, ExitSignal, ExitStatus}; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "test" { + return test(); + } + + let mut p = Command::new(&args[0]).arg("test").spawn().unwrap(); + // The invocation should fail due to the drop-flag sanity check. + assert!(!p.wait().unwrap().success()); +} + +#[derive(Debug)] +struct Corrupted { + x: u8 +} + +impl Drop for Corrupted { + fn drop(&mut self) { println!("dropping"); } +} + +fn test() { + { + let mut c1 = Corrupted { x: 1 }; + let mut c2 = Corrupted { x: 2 }; + unsafe { + let p1 = &mut c1 as *mut Corrupted as *mut u8; + let p2 = &mut c2 as *mut Corrupted as *mut u8; + for i in 0..std::mem::size_of::() { + // corrupt everything, *including the drop flag. + // + // (We corrupt via two different means to safeguard + // against the hypothetical assignment of the + // dtor_needed/dtor_done values to v and v+k. that + // happen to match with one of the corruption values + // below.) + *p1.offset(i as isize) += 2; + *p2.offset(i as isize) += 3; + } + } + // Here, at the end of the scope of `c1` and `c2`, the + // drop-glue should detect the corruption of (at least one of) + // the drop-flags. + } + println!("We should never get here."); +} diff --git a/src/test/run-pass/drop-flag-skip-sanity-check.rs b/src/test/run-pass/drop-flag-skip-sanity-check.rs new file mode 100644 index 00000000000..0b58bb16857 --- /dev/null +++ b/src/test/run-pass/drop-flag-skip-sanity-check.rs @@ -0,0 +1,67 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z force-dropflag-checks=off + +// Quick-and-dirty test to ensure -Z force-dropflag-checks=off works as +// expected. Note that the inlined drop-flag is slated for removal +// (RFC 320); when that happens, the -Z flag and this test should +// simply be removed. +// +// See also drop-flag-sanity-check.rs. + +use std::env; +use std::old_io::process::{Command, ExitSignal, ExitStatus}; + +fn main() { + let args: Vec = env::args().collect(); + if args.len() > 1 && args[1] == "test" { + return test(); + } + + let mut p = Command::new(&args[0]).arg("test").spawn().unwrap(); + // Invocatinn should succeed as drop-flag sanity check is skipped. + assert!(p.wait().unwrap().success()); +} + +#[derive(Debug)] +struct Corrupted { + x: u8 +} + +impl Drop for Corrupted { + fn drop(&mut self) { println!("dropping"); } +} + +fn test() { + { + let mut c1 = Corrupted { x: 1 }; + let mut c2 = Corrupted { x: 2 }; + unsafe { + let p1 = &mut c1 as *mut Corrupted as *mut u8; + let p2 = &mut c2 as *mut Corrupted as *mut u8; + for i in 0..std::mem::size_of::() { + // corrupt everything, *including the drop flag. + // + // (We corrupt via two different means to safeguard + // against the hypothetical assignment of the + // dtor_needed/dtor_done values to v and v+k. that + // happen to match with one of the corruption values + // below.) + *p1.offset(i as isize) += 2; + *p2.offset(i as isize) += 3; + } + } + // Here, at the end of the scope of `c1` and `c2`, the + // drop-glue should detect the corruption of (at least one of) + // the drop-flags. + } + println!("We should never get here."); +}