diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index d6a5efbd279..6f5ce350e6c 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -314,9 +314,11 @@ fn into_inner(self) -> Box<[u8]> { } // Turns this `CString` into an empty string to prevent -// memory unsafe code from working by accident. +// memory unsafe code from working by accident. Inline +// to prevent LLVM from optimizing it away in debug builds. #[stable(feature = "cstring_drop", since = "1.13.0")] impl Drop for CString { + #[inline] fn drop(&mut self) { unsafe { *self.inner.get_unchecked_mut(0) = 0; } } diff --git a/src/test/run-pass/cstring-drop.rs b/src/test/run-pass/cstring-drop.rs deleted file mode 100644 index 960391bb8de..00000000000 --- a/src/test/run-pass/cstring-drop.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// ignore-emscripten - -// Test that `CString::new("hello").unwrap().as_ptr()` pattern -// leads to failure. - -use std::env; -use std::ffi::{CString, CStr}; -use std::os::raw::c_char; -use std::process::{Command, Stdio}; - -fn main() { - let args: Vec = env::args().collect(); - if args.len() > 1 && args[1] == "child" { - // Repeat several times to be more confident that - // it is `Drop` for `CString` that does the cleanup, - // and not just some lucky UB. - let xs = vec![CString::new("Hello").unwrap(); 10]; - let ys = xs.iter().map(|s| s.as_ptr()).collect::>(); - drop(xs); - assert!(ys.into_iter().any(is_hello)); - return; - } - - let output = Command::new(&args[0]).arg("child").output().unwrap(); - assert!(!output.status.success()); -} - -fn is_hello(s: *const c_char) -> bool { - // `s` is a dangling pointer and reading it is technically - // undefined behavior. But we want to prevent the most diabolical - // kind of UB (apart from nasal demons): reading a value that was - // previously written. - // - // Segfaulting or reading an empty string is Ok, - // reading "Hello" is bad. - let s = unsafe { CStr::from_ptr(s) }; - let hello = CString::new("Hello").unwrap(); - s == hello.as_ref() -}