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:
commit
fd2f8a4536
1
configure
vendored
1
configure
vendored
@ -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"
|
||||
|
@ -1 +0,0 @@
|
||||
# rustbuild-only target
|
@ -1 +0,0 @@
|
||||
# rustbuild-only target
|
44
src/Cargo.lock
generated
44
src/Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
@ -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") {
|
||||
|
@ -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"));
|
||||
|
@ -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 {
|
||||
|
@ -124,6 +124,9 @@
|
||||
# disabled by default.
|
||||
#extended = false
|
||||
|
||||
# Build the sanitizer runtimes
|
||||
#sanitizers = false
|
||||
|
||||
# =============================================================================
|
||||
# General install configuration options
|
||||
# =============================================================================
|
||||
|
@ -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(),
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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
|
||||
|
25
src/ci/docker/dist-x86-linux/build-headers.sh
Executable file
25
src/ci/docker/dist-x86-linux/build-headers.sh
Executable 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
|
@ -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
|
@ -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
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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 {
|
||||
|
17
src/librustc_asan/Cargo.toml
Normal file
17
src/librustc_asan/Cargo.toml
Normal 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" }
|
39
src/librustc_asan/build.rs
Normal file
39
src/librustc_asan/build.rs
Normal 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
20
src/librustc_asan/lib.rs
Normal 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;
|
@ -126,6 +126,9 @@ pub enum Attribute {
|
||||
UWTable = 17,
|
||||
ZExt = 18,
|
||||
InReg = 19,
|
||||
SanitizeThread = 20,
|
||||
SanitizeAddress = 21,
|
||||
SanitizeMemory = 22,
|
||||
}
|
||||
|
||||
/// LLVMIntPredicate
|
||||
|
17
src/librustc_lsan/Cargo.toml
Normal file
17
src/librustc_lsan/Cargo.toml
Normal 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" }
|
39
src/librustc_lsan/build.rs
Normal file
39
src/librustc_lsan/build.rs
Normal 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
20
src/librustc_lsan/lib.rs
Normal 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;
|
@ -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);
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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()
|
||||
}
|
||||
|
17
src/librustc_msan/Cargo.toml
Normal file
17
src/librustc_msan/Cargo.toml
Normal 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" }
|
39
src/librustc_msan/build.rs
Normal file
39
src/librustc_msan/build.rs
Normal 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
20
src/librustc_msan/lib.rs
Normal 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;
|
@ -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:
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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
|
||||
|
17
src/librustc_tsan/Cargo.toml
Normal file
17
src/librustc_tsan/Cargo.toml
Normal 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" }
|
39
src/librustc_tsan/build.rs
Normal file
39
src/librustc_tsan/build.rs
Normal 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
20
src/librustc_tsan/lib.rs
Normal 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;
|
@ -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, "&{}{}{}", lt, m, **ty)
|
||||
write!(f, "&{}{}", lt, m)?;
|
||||
fmt_type(&ty, f, use_absolute)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>")?;
|
||||
|
@ -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"]
|
||||
|
@ -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
|
||||
///
|
||||
/// ```
|
||||
|
@ -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",
|
||||
|
@ -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"]
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -98,6 +98,9 @@ enum LLVMRustAttribute {
|
||||
UWTable = 17,
|
||||
ZExt = 18,
|
||||
InReg = 19,
|
||||
SanitizeThread = 20,
|
||||
SanitizeAddress = 21,
|
||||
SanitizeMemory = 22,
|
||||
};
|
||||
|
||||
typedef struct OpaqueRustString *RustStringRef;
|
||||
|
13
src/test/compile-fail/feature-gate-sanitizer-runtime.rs
Normal file
13
src/test/compile-fail/feature-gate-sanitizer-runtime.rs
Normal 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() {}
|
15
src/test/compile-fail/issue-27433.rs
Normal file
15
src/test/compile-fail/issue-27433.rs
Normal 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
|
||||
}
|
11
src/test/run-make/sanitizer-address/Makefile
Normal file
11
src/test/run-make/sanitizer-address/Makefile
Normal 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
|
14
src/test/run-make/sanitizer-address/overflow.rs
Normal file
14
src/test/run-make/sanitizer-address/overflow.rs
Normal 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) };
|
||||
}
|
8
src/test/run-make/sanitizer-dylib/Makefile
Normal file
8
src/test/run-make/sanitizer-dylib/Makefile
Normal 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
|
13
src/test/run-make/sanitizer-dylib/hello.rs
Normal file
13
src/test/run-make/sanitizer-dylib/hello.rs
Normal 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!");
|
||||
}
|
4
src/test/run-make/sanitizer-invalid-target/Makefile
Normal file
4
src/test/run-make/sanitizer-invalid-target/Makefile
Normal 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'
|
13
src/test/run-make/sanitizer-invalid-target/hello.rs
Normal file
13
src/test/run-make/sanitizer-invalid-target/hello.rs
Normal 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]
|
10
src/test/run-make/sanitizer-leak/Makefile
Normal file
10
src/test/run-make/sanitizer-leak/Makefile
Normal 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
|
16
src/test/run-make/sanitizer-leak/leak.rs
Normal file
16
src/test/run-make/sanitizer-leak/leak.rs
Normal 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);
|
||||
}
|
10
src/test/run-make/sanitizer-memory/Makefile
Normal file
10
src/test/run-make/sanitizer-memory/Makefile
Normal 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
|
16
src/test/run-make/sanitizer-memory/uninit.rs
Normal file
16
src/test/run-make/sanitizer-memory/uninit.rs
Normal 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];
|
||||
}
|
10
src/test/run-make/sanitizer-thread/Makefile
Normal file
10
src/test/run-make/sanitizer-thread/Makefile
Normal 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
|
21
src/test/run-make/sanitizer-thread/racy.rs
Normal file
21
src/test/run-make/sanitizer-thread/racy.rs
Normal 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();
|
||||
}
|
40
src/test/rustdoc/impl-disambiguation.rs
Normal file
40
src/test/rustdoc/impl-disambiguation.rs
Normal 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 {}
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user