Auto merge of #39677 - frewsxcv:rollup, r=frewsxcv

Rollup of 9 pull requests

- Successful merges: #37928, #38699, #39589, #39598, #39599, #39641, #39649, #39653, #39671
- Failed merges:
This commit is contained in:
bors 2017-02-09 05:58:29 +00:00
commit fd2f8a4536
60 changed files with 928 additions and 46 deletions

1
configure vendored
View File

@ -649,6 +649,7 @@ opt codegen-tests 1 "run the src/test/codegen tests"
opt option-checking 1 "complain about unrecognized options in this configure script"
opt ninja 0 "build LLVM using the Ninja generator (for MSVC, requires building in the correct environment)"
opt vendor 0 "enable usage of vendored Rust crates"
opt sanitizers 0 "build the sanitizer runtimes (asan, lsan, msan, tsan)"
# Optimization and debugging options. These may be overridden by the release channel, etc.
opt_nosave optimize 1 "build optimized rust code"

View File

@ -1 +0,0 @@
# rustbuild-only target

View File

@ -1 +0,0 @@
# rustbuild-only target

44
src/Cargo.lock generated
View File

@ -277,6 +277,16 @@ name = "rustc-serialize"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc_asan"
version = "0.0.0"
dependencies = [
"alloc_system 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
[[package]]
name = "rustc_back"
version = "0.0.0"
@ -410,6 +420,16 @@ dependencies = [
"rustc_bitflags 0.0.0",
]
[[package]]
name = "rustc_lsan"
version = "0.0.0"
dependencies = [
"alloc_system 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
[[package]]
name = "rustc_metadata"
version = "0.0.0"
@ -444,6 +464,16 @@ dependencies = [
"syntax_pos 0.0.0",
]
[[package]]
name = "rustc_msan"
version = "0.0.0"
dependencies = [
"alloc_system 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
[[package]]
name = "rustc_passes"
version = "0.0.0"
@ -525,6 +555,16 @@ dependencies = [
"syntax_pos 0.0.0",
]
[[package]]
name = "rustc_tsan"
version = "0.0.0"
dependencies = [
"alloc_system 0.0.0",
"build_helper 0.1.0",
"cmake 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"core 0.0.0",
]
[[package]]
name = "rustc_typeck"
version = "0.0.0"
@ -586,6 +626,10 @@ dependencies = [
"panic_abort 0.0.0",
"panic_unwind 0.0.0",
"rand 0.0.0",
"rustc_asan 0.0.0",
"rustc_lsan 0.0.0",
"rustc_msan 0.0.0",
"rustc_tsan 0.0.0",
"std_unicode 0.0.0",
"unwind 0.0.0",
]

View File

@ -242,6 +242,10 @@ pub fn compiletest(build: &Build,
cmd.env("RUSTC_BOOTSTRAP", "1");
build.add_rust_test_threads(&mut cmd);
if build.config.sanitizers {
cmd.env("SANITIZER_SUPPORT", "1");
}
cmd.arg("--adb-path").arg("adb");
cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);
if target.contains("android") {

View File

@ -51,6 +51,17 @@ pub fn std(build: &Build, target: &str, compiler: &Compiler) {
if compiler.stage == 0 && build.local_rebuild && !build.config.use_jemalloc {
features.push_str(" force_alloc_system");
}
if compiler.stage != 0 && build.config.sanitizers {
// This variable is used by the sanitizer runtime crates, e.g.
// rustc_lsan, to build the sanitizer runtime from C code
// When this variable is missing, those crates won't compile the C code,
// so we don't set this variable during stage0 where llvm-config is
// missing
// We also only build the runtimes when --enable-sanitizers (or its
// config.toml equivalent) is used
cargo.env("LLVM_CONFIG", build.llvm_config(target));
}
cargo.arg("--features").arg(features)
.arg("--manifest-path")
.arg(build.src.join("src/rustc/std_shim/Cargo.toml"));

View File

@ -48,6 +48,7 @@ pub struct Config {
pub target_config: HashMap<String, Target>,
pub full_bootstrap: bool,
pub extended: bool,
pub sanitizers: bool,
// llvm codegen options
pub llvm_assertions: bool,
@ -149,6 +150,7 @@ struct Build {
python: Option<String>,
full_bootstrap: Option<bool>,
extended: Option<bool>,
sanitizers: Option<bool>,
}
/// TOML representation of various global install decisions.
@ -294,6 +296,7 @@ impl Config {
set(&mut config.vendor, build.vendor);
set(&mut config.full_bootstrap, build.full_bootstrap);
set(&mut config.extended, build.extended);
set(&mut config.sanitizers, build.sanitizers);
if let Some(ref install) = toml.install {
config.prefix = install.prefix.clone().map(PathBuf::from);
@ -438,6 +441,7 @@ impl Config {
("VENDOR", self.vendor),
("FULL_BOOTSTRAP", self.full_bootstrap),
("EXTENDED", self.extended),
("SANITIZERS", self.sanitizers),
}
match key {

View File

@ -124,6 +124,9 @@
# disabled by default.
#extended = false
# Build the sanitizer runtimes
#sanitizers = false
# =============================================================================
# General install configuration options
# =============================================================================

View File

@ -515,9 +515,7 @@ pub fn cargo(build: &Build, stage: u32, target: &str) {
let branch = match &build.config.channel[..] {
"stable" |
"beta" => {
build.release.split(".").take(2).collect::<Vec<_>>().join(".")
}
"beta" => format!("rust-{}", build.release_num),
_ => "master".to_string(),
};

View File

@ -599,7 +599,8 @@ impl Build {
/// Get the space-separated set of activated features for the standard
/// library.
fn std_features(&self) -> String {
let mut features = "panic-unwind".to_string();
let mut features = "panic-unwind asan lsan msan tsan".to_string();
if self.config.debug_jemalloc {
features.push_str(" debug-jemalloc");
}

View File

@ -21,17 +21,7 @@ RUN yum upgrade -y && yum install -y \
ENV PATH=/rustroot/bin:$PATH
ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib
WORKDIR /tmp
# binutils < 2.22 has a bug where the 32-bit executables it generates
# immediately segfault in Rust, so we need to install our own binutils.
#
# See https://github.com/rust-lang/rust/issues/20440 for more info
COPY shared.sh build-binutils.sh /tmp/
RUN ./build-binutils.sh
# Need a newer version of gcc than centos has to compile LLVM nowadays
COPY build-gcc.sh /tmp/
RUN ./build-gcc.sh
# We need a build of openssl which supports SNI to download artifacts from
# static.rust-lang.org. This'll be used to link into libcurl below (and used
@ -49,6 +39,16 @@ RUN ./build-openssl.sh
COPY build-curl.sh /tmp/
RUN ./build-curl.sh
# binutils < 2.22 has a bug where the 32-bit executables it generates
# immediately segfault in Rust, so we need to install our own binutils.
#
# See https://github.com/rust-lang/rust/issues/20440 for more info
RUN ./build-binutils.sh
# Need a newer version of gcc than centos has to compile LLVM nowadays
COPY build-gcc.sh /tmp/
RUN ./build-gcc.sh
# CentOS 5.5 has Python 2.4 by default, but LLVM needs 2.7+
COPY build-python.sh /tmp/
RUN ./build-python.sh
@ -63,6 +63,11 @@ RUN ./build-git.sh
COPY build-cmake.sh /tmp/
RUN ./build-cmake.sh
# for sanitizers, we need kernel headers files newer than the ones CentOS ships
# with so we install newer ones here
COPY build-headers.sh /tmp/
RUN ./build-headers.sh
RUN curl -Lo /rustroot/dumb-init \
https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 && \
chmod +x /rustroot/dumb-init
@ -76,5 +81,5 @@ RUN curl -L https://api.pub.build.mozilla.org/tooltool/sha512/$SCCACHE_DIGEST |
ENV HOSTS=i686-unknown-linux-gnu
ENV HOSTS=$HOSTS,x86_64-unknown-linux-gnu
ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended
ENV RUST_CONFIGURE_ARGS --host=$HOSTS --enable-extended --enable-sanitizers
ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS

View File

@ -0,0 +1,25 @@
#!/bin/bash
# Copyright 2017 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.
set -ex
source shared.sh
curl https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.2.84.tar.xz | unxz | tar x
cd linux-3.2.84
hide_output make mrproper
hide_output make INSTALL_HDR_PATH=dest headers_install
find dest/include \( -name .install -o -name ..install.cmd \) -delete
yes | cp -fr dest/include/* /usr/include
cd ..
rm -rf linux-3.2.84

View File

@ -22,5 +22,5 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
rm dumb-init_*.deb
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu
ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu --enable-sanitizers
ENV SCRIPT python2.7 ../x.py test && python2.7 ../x.py dist

@ -1 +1 @@
Subproject commit a8fc4c169fac43a5dc204d4fd56ddb1739f8c178
Subproject commit d30da544a8afc5d78391dee270bdf40e74a215d3

View File

@ -1291,15 +1291,18 @@ guaranteed to refer to the same memory address.
Constant values must not have destructors, and otherwise permit most forms of
data. Constants may refer to the address of other constants, in which case the
address will have the `static` lifetime. The compiler is, however, still at
liberty to translate the constant many times, so the address referred to may not
be stable.
address will have elided lifetimes where applicable, otherwise in most cases
defaulting to the `static` lifetime. (See below on [static lifetime elision].)
The compiler is, however, still at liberty to translate the constant many times,
so the address referred to may not be stable.
[static lifetime elision]: #static-lifetime-elision
Constants must be explicitly typed. The type may be `bool`, `char`, a number, or
a type derived from those primitive types. The derived types are references with
the `static` lifetime, fixed-size arrays, tuples, enum variants, and structs.
```
```rust
const BIT1: u32 = 1 << 0;
const BIT2: u32 = 1 << 1;
@ -1317,6 +1320,8 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
};
```
### Static items
A *static item* is similar to a *constant*, except that it represents a precise
@ -1351,7 +1356,7 @@ running in the same process.
Mutable statics are still very useful, however. They can be used with C
libraries and can also be bound from C libraries (in an `extern` block).
```
```rust
# fn atomic_add(_: &mut u32, _: u32) -> u32 { 2 }
static mut LEVELS: u32 = 0;
@ -1375,6 +1380,53 @@ unsafe fn bump_levels_unsafe2() -> u32 {
Mutable statics have the same restrictions as normal statics, except that the
type of the value is not required to ascribe to `Sync`.
#### `'static` lifetime elision
[Unstable] Both constant and static declarations of reference types have
*implicit* `'static` lifetimes unless an explicit lifetime is specified. As
such, the constant declarations involving `'static` above may be written
without the lifetimes. Returning to our previous example:
```rust
# #![feature(static_in_const)]
const BIT1: u32 = 1 << 0;
const BIT2: u32 = 1 << 1;
const BITS: [u32; 2] = [BIT1, BIT2];
const STRING: &str = "bitstring";
struct BitsNStrings<'a> {
mybits: [u32; 2],
mystring: &'a str,
}
const BITS_N_STRINGS: BitsNStrings = BitsNStrings {
mybits: BITS,
mystring: STRING,
};
```
Note that if the `static` or `const` items include function or closure
references, which themselves include references, the compiler will first try the
standard elision rules ([see discussion in the nomicon][elision-nomicon]). If it
is unable to resolve the lifetimes by its usual rules, it will default to using
the `'static` lifetime. By way of example:
[elision-nomicon]: https://doc.rust-lang.org/nomicon/lifetime-elision.html
```rust,ignore
// Resolved as `fn<'a>(&'a str) -> &'a str`.
const RESOLVED_SINGLE: fn(&str) -> &str = ..
// Resolved as `Fn<'a, 'b, 'c>(&'a Foo, &'b Bar, &'c Baz) -> usize`.
const RESOLVED_MULTIPLE: Fn(&Foo, &Bar, &Baz) -> usize = ..
// There is insufficient information to bound the return reference lifetime
// relative to the argument lifetimes, so the signature is resolved as
// `Fn(&'static Foo, &'static Bar) -> &'static Baz`.
const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = ..
```
### Traits
A _trait_ describes an abstract interface that types can
@ -2072,7 +2124,9 @@ macro scope.
### Miscellaneous attributes
- `deprecated` - mark the item as deprecated; the full attribute is `#[deprecated(since = "crate version", note = "...")`, where both arguments are optional.
- `deprecated` - mark the item as deprecated; the full attribute is
`#[deprecated(since = "crate version", note = "...")`, where both arguments
are optional.
- `export_name` - on statics and functions, this determines the name of the
exported symbol.
- `link_section` - on statics and functions, this specifies the section of the
@ -2489,9 +2543,6 @@ The currently implemented features of the reference compiler are:
into a Rust program. This capability, especially the signature for the
annotated function, is subject to change.
* `static_in_const` - Enables lifetime elision with a `'static` default for
`const` and `static` item declarations.
* `thread_local` - The usage of the `#[thread_local]` attribute is experimental
and should be seen as unstable. This attribute is used to
declare a `static` as being unique per-thread leveraging

View File

@ -229,6 +229,7 @@ pub trait CrateStore<'tcx> {
fn is_allocator(&self, cnum: CrateNum) -> bool;
fn is_panic_runtime(&self, cnum: CrateNum) -> bool;
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool;
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool;
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy;
fn extern_crate(&self, cnum: CrateNum) -> Option<ExternCrate>;
/// The name of the crate as it is referred to in source code of the current
@ -390,6 +391,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn is_allocator(&self, cnum: CrateNum) -> bool { bug!("is_allocator") }
fn is_panic_runtime(&self, cnum: CrateNum) -> bool { bug!("is_panic_runtime") }
fn is_compiler_builtins(&self, cnum: CrateNum) -> bool { bug!("is_compiler_builtins") }
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool { bug!("is_sanitizer_runtime") }
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
bug!("panic_strategy")
}

View File

@ -51,6 +51,14 @@ pub struct Config {
pub uint_type: UintTy,
}
#[derive(Clone)]
pub enum Sanitizer {
Address,
Leak,
Memory,
Thread,
}
#[derive(Clone, Copy, PartialEq, Hash)]
pub enum OptLevel {
No, // -O0
@ -626,11 +634,13 @@ macro_rules! options {
Some("a number");
pub const parse_panic_strategy: Option<&'static str> =
Some("either `panic` or `abort`");
pub const parse_sanitizer: Option<&'static str> =
Some("one of: `address`, `leak`, `memory` or `thread`");
}
#[allow(dead_code)]
mod $mod_set {
use super::{$struct_name, Passes, SomePasses, AllPasses};
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer};
use rustc_back::PanicStrategy;
$(
@ -751,6 +761,17 @@ macro_rules! options {
}
true
}
fn parse_sanitizer(slote: &mut Option<Sanitizer>, v: Option<&str>) -> bool {
match v {
Some("address") => *slote = Some(Sanitizer::Address),
Some("leak") => *slote = Some(Sanitizer::Leak),
Some("memory") => *slote = Some(Sanitizer::Memory),
Some("thread") => *slote = Some(Sanitizer::Thread),
_ => return false,
}
true
}
}
) }
@ -949,6 +970,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"encode MIR of all functions into the crate metadata"),
osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
"pass `-install_name @rpath/...` to the OSX linker"),
sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [UNTRACKED],
"Use a sanitizer"),
}
pub fn default_lib_output() -> CrateType {

View File

@ -0,0 +1,17 @@
[package]
authors = ["The Rust Project Developers"]
build = "build.rs"
name = "rustc_asan"
version = "0.0.0"
[lib]
name = "rustc_asan"
path = "lib.rs"
[build-dependencies]
build_helper = { path = "../build_helper" }
cmake = "0.1.18"
[dependencies]
alloc_system = { path = "../liballoc_system" }
core = { path = "../libcore" }

View File

@ -0,0 +1,39 @@
// 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.
extern crate build_helper;
extern crate cmake;
use std::path::PathBuf;
use std::env;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let dst = Config::new("../compiler-rt")
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
.define("COMPILER_RT_BUILD_BUILTINS", "OFF")
.define("COMPILER_RT_BUILD_XRAY", "OFF")
.define("LLVM_CONFIG_PATH", llvm_config)
.build_target("asan")
.build();
println!("cargo:rustc-link-search=native={}",
dst.join("build/lib/linux").display());
println!("cargo:rustc-link-lib=static=clang_rt.asan-x86_64");
build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR")
.unwrap())
.join("../compiler-rt"));
}
println!("cargo:rerun-if-changed=build.rs");
}

20
src/librustc_asan/lib.rs Normal file
View File

@ -0,0 +1,20 @@
// 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.
#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
#![unstable(feature = "sanitizer_runtime_lib",
reason = "internal implementation detail of sanitizers",
issue = "0")]
extern crate alloc_system;

View File

@ -126,6 +126,9 @@ pub enum Attribute {
UWTable = 17,
ZExt = 18,
InReg = 19,
SanitizeThread = 20,
SanitizeAddress = 21,
SanitizeMemory = 22,
}
/// LLVMIntPredicate

View File

@ -0,0 +1,17 @@
[package]
authors = ["The Rust Project Developers"]
build = "build.rs"
name = "rustc_lsan"
version = "0.0.0"
[lib]
name = "rustc_lsan"
path = "lib.rs"
[build-dependencies]
build_helper = { path = "../build_helper" }
cmake = "0.1.18"
[dependencies]
alloc_system = { path = "../liballoc_system" }
core = { path = "../libcore" }

View File

@ -0,0 +1,39 @@
// 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.
extern crate build_helper;
extern crate cmake;
use std::path::PathBuf;
use std::env;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let dst = Config::new("../compiler-rt")
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
.define("COMPILER_RT_BUILD_BUILTINS", "OFF")
.define("COMPILER_RT_BUILD_XRAY", "OFF")
.define("LLVM_CONFIG_PATH", llvm_config)
.build_target("lsan")
.build();
println!("cargo:rustc-link-search=native={}",
dst.join("build/lib/linux").display());
println!("cargo:rustc-link-lib=static=clang_rt.lsan-x86_64");
build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR")
.unwrap())
.join("../compiler-rt"));
}
println!("cargo:rerun-if-changed=build.rs");
}

20
src/librustc_lsan/lib.rs Normal file
View File

@ -0,0 +1,20 @@
// 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.
#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
#![unstable(feature = "sanitizer_runtime_lib",
reason = "internal implementation detail of sanitizers",
issue = "0")]
extern crate alloc_system;

View File

@ -17,7 +17,8 @@ use schema::CrateRoot;
use rustc::hir::def_id::{CrateNum, DefIndex};
use rustc::hir::svh::Svh;
use rustc::middle::cstore::DepKind;
use rustc::session::{config, Session};
use rustc::session::Session;
use rustc::session::config::{Sanitizer, self};
use rustc_back::PanicStrategy;
use rustc::session::search_paths::PathKind;
use rustc::middle;
@ -786,6 +787,64 @@ impl<'a> CrateLoader<'a> {
&|data| data.needs_panic_runtime());
}
fn inject_sanitizer_runtime(&mut self) {
if let Some(ref sanitizer) = self.sess.opts.debugging_opts.sanitizer {
// Sanitizers can only be used with x86_64 Linux executables linked
// to `std`
if self.sess.target.target.llvm_target != "x86_64-unknown-linux-gnu" {
self.sess.err(&format!("Sanitizers only work with the \
`x86_64-unknown-linux-gnu` target."));
return
}
if !self.sess.crate_types.borrow().iter().all(|ct| {
match *ct {
// Link the runtime
config::CrateTypeExecutable => true,
// This crate will be compiled with the required
// instrumentation pass
config::CrateTypeRlib => false,
_ => {
self.sess.err(&format!("Only executables and rlibs can be \
compiled with `-Z sanitizer`"));
false
}
}
}) {
return
}
let mut uses_std = false;
self.cstore.iter_crate_data(|_, data| {
if data.name == "std" {
uses_std = true;
}
});
if uses_std {
let name = match *sanitizer {
Sanitizer::Address => "rustc_asan",
Sanitizer::Leak => "rustc_lsan",
Sanitizer::Memory => "rustc_msan",
Sanitizer::Thread => "rustc_tsan",
};
info!("loading sanitizer: {}", name);
let symbol = Symbol::intern(name);
let dep_kind = DepKind::Implicit;
let (_, data) =
self.resolve_crate(&None, symbol, symbol, None, DUMMY_SP,
PathKind::Crate, dep_kind);
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
if !data.is_sanitizer_runtime() {
self.sess.err(&format!("the crate `{}` is not a sanitizer runtime",
name));
}
}
}
}
fn inject_allocator_crate(&mut self) {
// Make sure that we actually need an allocator, if none of our
// dependencies need one then we definitely don't!
@ -982,6 +1041,9 @@ impl<'a> CrateLoader<'a> {
impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
fn postprocess(&mut self, krate: &ast::Crate) {
// inject the sanitizer runtime before the allocator runtime because all
// sanitizers force the use of the `alloc_system` allocator
self.inject_sanitizer_runtime();
self.inject_allocator_crate();
self.inject_panic_runtime(krate);

View File

@ -297,6 +297,11 @@ impl CrateMetadata {
attr::contains_name(&attrs, "compiler_builtins")
}
pub fn is_sanitizer_runtime(&self) -> bool {
let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
attr::contains_name(&attrs, "sanitizer_runtime")
}
pub fn is_no_builtins(&self) -> bool {
let attrs = self.get_item_attrs(CRATE_DEF_INDEX);
attr::contains_name(&attrs, "no_builtins")

View File

@ -297,6 +297,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
self.get_crate_data(cnum).is_compiler_builtins()
}
fn is_sanitizer_runtime(&self, cnum: CrateNum) -> bool {
self.get_crate_data(cnum).is_sanitizer_runtime()
}
fn panic_strategy(&self, cnum: CrateNum) -> PanicStrategy {
self.get_crate_data(cnum).panic_strategy()
}

View File

@ -0,0 +1,17 @@
[package]
authors = ["The Rust Project Developers"]
build = "build.rs"
name = "rustc_msan"
version = "0.0.0"
[lib]
name = "rustc_msan"
path = "lib.rs"
[build-dependencies]
build_helper = { path = "../build_helper" }
cmake = "0.1.18"
[dependencies]
alloc_system = { path = "../liballoc_system" }
core = { path = "../libcore" }

View File

@ -0,0 +1,39 @@
// 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.
extern crate build_helper;
extern crate cmake;
use std::path::PathBuf;
use std::env;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let dst = Config::new("../compiler-rt")
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
.define("COMPILER_RT_BUILD_BUILTINS", "OFF")
.define("COMPILER_RT_BUILD_XRAY", "OFF")
.define("LLVM_CONFIG_PATH", llvm_config)
.build_target("msan")
.build();
println!("cargo:rustc-link-search=native={}",
dst.join("build/lib/linux").display());
println!("cargo:rustc-link-lib=static=clang_rt.msan-x86_64");
build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR")
.unwrap())
.join("../compiler-rt"));
}
println!("cargo:rerun-if-changed=build.rs");
}

20
src/librustc_msan/lib.rs Normal file
View File

@ -0,0 +1,20 @@
// 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.
#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
#![unstable(feature = "sanitizer_runtime_lib",
reason = "internal implementation detail of sanitizers",
issue = "0")]
extern crate alloc_system;

View File

@ -1031,6 +1031,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// symbols from the dylib.
let src = sess.cstore.used_crate_source(cnum);
match data[cnum.as_usize() - 1] {
_ if sess.cstore.is_sanitizer_runtime(cnum) => {
link_sanitizer_runtime(cmd, sess, tmpdir, cnum);
}
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
_ if sess.cstore.is_compiler_builtins(cnum) => {
@ -1048,6 +1051,8 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
}
}
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
// We must always link the `compiler_builtins` crate statically. Even if it
// was already "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic`
// is used)
@ -1064,6 +1069,34 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
}
}
// We must link the sanitizer runtime using -Wl,--whole-archive but since
// it's packed in a .rlib, it contains stuff that are not objects that will
// make the linker error. So we must remove those bits from the .rlib before
// linking it.
fn link_sanitizer_runtime(cmd: &mut Linker,
sess: &Session,
tmpdir: &Path,
cnum: CrateNum) {
let src = sess.cstore.used_crate_source(cnum);
let cratepath = &src.rlib.unwrap().0;
let dst = tmpdir.join(cratepath.file_name().unwrap());
let cfg = archive_config(sess, &dst, Some(cratepath));
let mut archive = ArchiveBuilder::new(cfg);
archive.update_symbols();
for f in archive.src_files() {
if f.ends_with("bytecode.deflate") ||
f == sess.cstore.metadata_filename() {
archive.remove_file(&f);
continue
}
}
archive.build();
cmd.link_whole_rlib(&dst);
}
// Adds the static "rlib" versions of all crates to the command line.
// There's a bit of magic which happens here specifically related to LTO and
// dynamic libraries. Specifically:

View File

@ -12,7 +12,7 @@ use back::lto;
use back::link::{get_linker, remove};
use back::symbol_export::ExportedSymbols;
use rustc_incremental::{save_trans_partition, in_incr_comp_dir};
use session::config::{OutputFilenames, OutputTypes, Passes, SomePasses, AllPasses};
use session::config::{OutputFilenames, OutputTypes, Passes, SomePasses, AllPasses, Sanitizer};
use session::Session;
use session::config::{self, OutputType};
use llvm;
@ -679,6 +679,22 @@ pub fn run_passes(sess: &Session,
let mut modules_config = ModuleConfig::new(tm, sess.opts.cg.passes.clone());
let mut metadata_config = ModuleConfig::new(tm, vec![]);
if let Some(ref sanitizer) = sess.opts.debugging_opts.sanitizer {
match *sanitizer {
Sanitizer::Address => {
modules_config.passes.push("asan".to_owned());
modules_config.passes.push("asan-module".to_owned());
}
Sanitizer::Memory => {
modules_config.passes.push("msan".to_owned())
}
Sanitizer::Thread => {
modules_config.passes.push("tsan".to_owned())
}
_ => {}
}
}
modules_config.opt_level = Some(get_llvm_opt_level(sess.opts.optimize));
modules_config.opt_size = Some(get_llvm_opt_size(sess.opts.optimize));

View File

@ -23,6 +23,7 @@
use llvm::{self, ValueRef};
use llvm::AttributePlace::Function;
use rustc::ty;
use rustc::session::config::Sanitizer;
use abi::{Abi, FnType};
use attributes;
use context::CrateContext;
@ -72,6 +73,21 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty:
llvm::Attribute::NoRedZone.apply_llfn(Function, llfn);
}
if let Some(ref sanitizer) = ccx.tcx().sess.opts.debugging_opts.sanitizer {
match *sanitizer {
Sanitizer::Address => {
llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn);
},
Sanitizer::Memory => {
llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn);
},
Sanitizer::Thread => {
llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn);
},
_ => {}
}
}
// If we're compiling the compiler-builtins crate, e.g. the equivalent of
// compiler-rt, then we want to implicitly compile everything with hidden
// visibility as we're going to link this object all over the place but

View File

@ -0,0 +1,17 @@
[package]
authors = ["The Rust Project Developers"]
build = "build.rs"
name = "rustc_tsan"
version = "0.0.0"
[lib]
name = "rustc_tsan"
path = "lib.rs"
[build-dependencies]
build_helper = { path = "../build_helper" }
cmake = "0.1.18"
[dependencies]
alloc_system = { path = "../liballoc_system" }
core = { path = "../libcore" }

View File

@ -0,0 +1,39 @@
// 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.
extern crate build_helper;
extern crate cmake;
use std::path::PathBuf;
use std::env;
use cmake::Config;
fn main() {
if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
let dst = Config::new("../compiler-rt")
.define("COMPILER_RT_BUILD_SANITIZERS", "ON")
.define("COMPILER_RT_BUILD_BUILTINS", "OFF")
.define("COMPILER_RT_BUILD_XRAY", "OFF")
.define("LLVM_CONFIG_PATH", llvm_config)
.build_target("tsan")
.build();
println!("cargo:rustc-link-search=native={}",
dst.join("build/lib/linux").display());
println!("cargo:rustc-link-lib=static=clang_rt.tsan-x86_64");
build_helper::rerun_if_changed_anything_in_dir(&PathBuf::from(env::var("CARGO_MANIFEST_DIR")
.unwrap())
.join("../compiler-rt"));
}
println!("cargo:rerun-if-changed=build.rs");
}

20
src/librustc_tsan/lib.rs Normal file
View File

@ -0,0 +1,20 @@
// 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.
#![cfg_attr(not(stage0), feature(sanitizer_runtime))]
#![cfg_attr(not(stage0), sanitizer_runtime)]
#![feature(alloc_system)]
#![feature(staged_api)]
#![no_std]
#![unstable(feature = "sanitizer_runtime_lib",
reason = "internal implementation detail of sanitizers",
issue = "0")]
extern crate alloc_system;

View File

@ -671,9 +671,11 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
}
_ => {
if f.alternate() {
write!(f, "&{}{}{:#}", lt, m, **ty)
write!(f, "&{}{}", lt, m)?;
fmt_type(&ty, f, use_absolute)
} else {
write!(f, "&amp;{}{}{}", lt, m, **ty)
write!(f, "&amp;{}{}", lt, m)?;
fmt_type(&ty, f, use_absolute)
}
}
}

View File

@ -2132,10 +2132,23 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
<ul class='item-list' id='implementors-list'>
")?;
if let Some(implementors) = cache.implementors.get(&it.def_id) {
let mut implementor_count: FxHashMap<&str, usize> = FxHashMap();
// The DefId is for the first Type found with that name. The bool is
// if any Types with the same name but different DefId have been found.
let mut implementor_dups: FxHashMap<&str, (DefId, bool)> = FxHashMap();
for implementor in implementors {
if let clean::Type::ResolvedPath {ref path, ..} = implementor.impl_.for_ {
*implementor_count.entry(path.last_name()).or_insert(0) += 1;
match implementor.impl_.for_ {
clean::ResolvedPath { ref path, did, is_generic: false, .. } |
clean::BorrowedRef {
type_: box clean::ResolvedPath { ref path, did, is_generic: false, .. },
..
} => {
let &mut (prev_did, ref mut has_duplicates) =
implementor_dups.entry(path.last_name()).or_insert((did, false));
if prev_did != did {
*has_duplicates = true;
}
}
_ => {}
}
}
@ -2143,12 +2156,13 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
write!(w, "<li><code>")?;
// If there's already another implementor that has the same abbridged name, use the
// full path, for example in `std::iter::ExactSizeIterator`
let use_absolute = if let clean::Type::ResolvedPath {
ref path, ..
} = implementor.impl_.for_ {
implementor_count[path.last_name()] > 1
} else {
false
let use_absolute = match implementor.impl_.for_ {
clean::ResolvedPath { ref path, is_generic: false, .. } |
clean::BorrowedRef {
type_: box clean::ResolvedPath { ref path, is_generic: false, .. },
..
} => implementor_dups[path.last_name()].1,
_ => false,
};
fmt_impl_for_trait_page(&implementor.impl_, w, use_absolute)?;
writeln!(w, "</code></li>")?;

View File

@ -23,13 +23,23 @@ compiler_builtins = { path = "../libcompiler_builtins" }
std_unicode = { path = "../libstd_unicode" }
unwind = { path = "../libunwind" }
[target.x86_64-unknown-linux-gnu.dependencies]
rustc_asan = { path = "../librustc_asan", optional = true }
rustc_lsan = { path = "../librustc_lsan", optional = true }
rustc_msan = { path = "../librustc_msan", optional = true }
rustc_tsan = { path = "../librustc_tsan", optional = true }
[build-dependencies]
build_helper = { path = "../build_helper" }
gcc = "0.3.27"
[features]
asan = ["rustc_asan"]
backtrace = []
debug-jemalloc = ["alloc_jemalloc/debug"]
jemalloc = ["alloc_jemalloc"]
force_alloc_system = []
lsan = ["rustc_lsan"]
msan = ["rustc_msan"]
panic-unwind = ["panic_unwind"]
tsan = ["rustc_tsan"]

View File

@ -400,15 +400,19 @@ pub struct JoinPathsError {
inner: os_imp::JoinPathsError
}
/// Joins a collection of `Path`s appropriately for the `PATH`
/// Joins a collection of [`Path`]s appropriately for the `PATH`
/// environment variable.
///
/// Returns an `OsString` on success.
/// Returns an [`OsString`] on success.
///
/// Returns an `Err` (containing an error message) if one of the input
/// `Path`s contains an invalid character for constructing the `PATH`
/// Returns an [`Err`][err] (containing an error message) if one of the input
/// [`Path`]s contains an invalid character for constructing the `PATH`
/// variable (a double quote on Windows or a colon on Unix).
///
/// [`Path`]: ../../std/path/struct.Path.html
/// [`OsString`]: ../../std/ffi/struct.OsString.html
/// [err]: ../../std/result/enum.Result.html#variant.Err
///
/// # Examples
///
/// ```

View File

@ -328,6 +328,10 @@ declare_features! (
// `extern "msp430-interrupt" fn()`
(active, abi_msp430_interrupt, "1.16.0", Some(38487)),
// Used to identify crates that contain sanitizer runtimes
// rustc internal
(active, sanitizer_runtime, "1.17.0", None),
);
declare_features! (
@ -647,6 +651,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
contains compiler-rt intrinsics and will never be \
stable",
cfg_fn!(compiler_builtins))),
("sanitizer_runtime", Whitelisted, Gated(Stability::Unstable,
"sanitizer_runtime",
"the `#[sanitizer_runtime]` attribute is used to \
identify crates that contain the runtime of a \
sanitizer and will never be stable",
cfg_fn!(sanitizer_runtime))),
("allow_internal_unstable", Normal, Gated(Stability::Unstable,
"allow_internal_unstable",

View File

@ -35,8 +35,12 @@ core = { path = "../../libcore" }
# Reexport features from std
[features]
asan = ["std/asan"]
backtrace = ["std/backtrace"]
debug-jemalloc = ["std/debug-jemalloc"]
jemalloc = ["std/jemalloc"]
force_alloc_system = ["std/force_alloc_system"]
lsan = ["std/lsan"]
msan = ["std/msan"]
panic-unwind = ["std/panic-unwind"]
tsan = ["std/tsan"]

View File

@ -148,6 +148,12 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
return Attribute::ZExt;
case InReg:
return Attribute::InReg;
case SanitizeThread:
return Attribute::SanitizeThread;
case SanitizeAddress:
return Attribute::SanitizeAddress;
case SanitizeMemory:
return Attribute::SanitizeMemory;
}
llvm_unreachable("bad AttributeKind");
}

View File

@ -98,6 +98,9 @@ enum LLVMRustAttribute {
UWTable = 17,
ZExt = 18,
InReg = 19,
SanitizeThread = 20,
SanitizeAddress = 21,
SanitizeMemory = 22,
};
typedef struct OpaqueRustString *RustStringRef;

View File

@ -0,0 +1,13 @@
// 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.
#![sanitizer_runtime] //~ ERROR the `#[sanitizer_runtime]` attribute is
fn main() {}

View File

@ -0,0 +1,15 @@
// Copyright 2017 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.
fn main() {
let foo = 42u32;
const FOO : u32 = foo;
//~^ ERROR attempt to use a non-constant value in a constant
}

View File

@ -0,0 +1,11 @@
-include ../tools.mk
# NOTE the address sanitizer only supports x86_64 linux
ifdef SANITIZER_SUPPORT
all:
$(RUSTC) -g -Z sanitizer=address -Z print-link-args overflow.rs | grep -q librustc_asan
$(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow
else
all:
endif

View File

@ -0,0 +1,14 @@
// Copyright 2017 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.
fn main() {
let xs = [0, 1, 2, 3];
let y = unsafe { *xs.as_ptr().offset(4) };
}

View File

@ -0,0 +1,8 @@
-include ../tools.mk
ifeq ($(TARGET),x86_64-unknown-linux-gnu)
all:
$(RUSTC) -Z sanitizer=leak --crate-type dylib --target $(TARGET) hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`'
else
all:
endif

View File

@ -0,0 +1,13 @@
// Copyright 2017 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.
fn main() {
println!("Hello, world!");
}

View File

@ -0,0 +1,4 @@
-include ../tools.mk
all:
$(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | grep -q 'Sanitizers only work with the `x86_64-unknown-linux-gnu` target'

View File

@ -0,0 +1,13 @@
// Copyright 2017 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(no_core)]
#![no_core]
#![no_main]

View File

@ -0,0 +1,10 @@
-include ../tools.mk
ifdef SANITIZER_SUPPORT
all:
$(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | grep -q librustc_lsan
$(TMPDIR)/leak 2>&1 | grep -q 'detected memory leaks'
else
all:
endif

View File

@ -0,0 +1,16 @@
// Copyright 2017 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::mem;
fn main() {
let xs = vec![1, 2, 3, 4];
mem::forget(xs);
}

View File

@ -0,0 +1,10 @@
-include ../tools.mk
ifdef SANITIZER_SUPPORT
all:
$(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | grep -q librustc_msan
$(TMPDIR)/uninit 2>&1 | grep -q use-of-uninitialized-value
else
all:
endif

View File

@ -0,0 +1,16 @@
// Copyright 2017 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::mem;
fn main() {
let xs: [u8; 4] = unsafe { mem::uninitialized() };
let y = xs[0] + xs[1];
}

View File

@ -0,0 +1,10 @@
-include ../tools.mk
ifdef SANITIZER_SUPPORT
all:
$(RUSTC) -g -Z sanitizer=thread -Z print-link-args racy.rs | grep -q librustc_tsan
$(TMPDIR)/racy 2>&1 | grep -q 'data race'
else
all:
endif

View File

@ -0,0 +1,21 @@
// Copyright 2017 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::thread;
static mut ANSWER: i32 = 0;
fn main() {
let t1 = thread::spawn(|| unsafe { ANSWER = 42 });
unsafe {
ANSWER = 24;
}
t1.join().ok();
}

View File

@ -0,0 +1,40 @@
// Copyright 2017 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.
#![crate_name = "foo"]
pub trait Foo {}
pub struct Bar<T> { field: T }
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl Foo for Bar<u8>"
impl Foo for Bar<u8> {}
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl Foo for Bar<u16>"
impl Foo for Bar<u16> {}
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl<'a> Foo for &'a Bar<u8>"
impl<'a> Foo for &'a Bar<u8> {}
pub mod mod1 {
pub struct Baz {}
}
pub mod mod2 {
pub enum Baz {}
}
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl Foo for foo::mod1::Baz"
impl Foo for mod1::Baz {}
// @has foo/trait.Foo.html '//*[@class="item-list"]//code' \
// "impl<'a> Foo for &'a foo::mod2::Baz"
impl<'a> Foo for &'a mod2::Baz {}

View File

@ -326,6 +326,8 @@ impl Builder {
fn filename(&self, component: &str, target: &str) -> String {
if component == "rust-src" {
format!("rust-src-{}.tar.gz", self.channel)
} else if component == "cargo" {
format!("cargo-nightly-{}.tar.gz", target)
} else {
format!("{}-{}-{}.tar.gz", component, self.channel, target)
}