diff options
| author | bors <bors@rust-lang.org> | 2016-09-13 15:08:12 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-09-13 15:08:12 -0700 |
| commit | b1363a73ede57ae595f3a1be2bb75d308ba4f7f6 (patch) | |
| tree | 145ce98f3c6eeea3723fd23ae7610b55c8676542 /src | |
| parent | 2fd060815f9e9c4ae787cb1cd44df51aeb91fe6e (diff) | |
| parent | 848cfe20a01b3d43d4c9838bd7d9b0da32dace42 (diff) | |
| download | rust-b1363a73ede57ae595f3a1be2bb75d308ba4f7f6.tar.gz rust-b1363a73ede57ae595f3a1be2bb75d308ba4f7f6.zip | |
Auto merge of #35021 - japaric:rustc-builtins, r=alexcrichton
crate-ify compiler-rt into compiler-builtins libcompiler-rt.a is dead, long live libcompiler-builtins.rlib This commit moves the logic that used to build libcompiler-rt.a into a compiler-builtins crate on top of the core crate and below the std crate. This new crate still compiles the compiler-rt instrinsics using gcc-rs but produces an .rlib instead of a static library. Also, with this commit rustc no longer passes -lcompiler-rt to the linker. This effectively makes the "no-compiler-rt" field of target specifications a no-op. Users of `no_std` will have to explicitly add the compiler-builtins crate to their crate dependency graph *if* they need the compiler-rt intrinsics - this is a [breaking-change]. Users of the `std` have to do nothing extra as the std crate depends on compiler-builtins. Finally, this a step towards lazy compilation of std with Cargo as the compiler-rt intrinsics can now be built by Cargo instead of having to be supplied by the user by some other method. closes #34400 --- r? @alexcrichton
Diffstat (limited to 'src')
23 files changed, 552 insertions, 449 deletions
diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index a466e2e6897..a1e286e162f 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -28,7 +28,6 @@ pub fn clean(build: &Build) { let out = build.out.join(host); - rm_rf(build, &out.join("compiler-rt")); rm_rf(build, &out.join("doc")); for stage in 0..4 { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index e87669ba08c..60bf52a514c 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -35,13 +35,23 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { println!("Building stage{} std artifacts ({} -> {})", compiler.stage, compiler.host, target); - // Move compiler-rt into place as it'll be required by the compiler when - // building the standard library to link the dylib of libstd let libdir = build.sysroot_libdir(compiler, target); let _ = fs::remove_dir_all(&libdir); t!(fs::create_dir_all(&libdir)); - copy(&build.compiler_rt_built.borrow()[target], - &libdir.join(staticlib("compiler-rt", target))); + // FIXME(stage0) remove this `if` after the next snapshot + // The stage0 compiler still passes the `-lcompiler-rt` flag to the linker but now `bootstrap` + // never builds a `libcopmiler-rt.a`! We'll fill the hole by simply copying stage0's + // `libcompiler-rt.a` to where the stage1's one is expected (though we could as well just use + // an empty `.a` archive). Note that the symbols of that stage0 `libcompiler-rt.a` won't make + // it to the final binary because now `libcore.rlib` also contains the symbols that + // `libcompiler-rt.a` provides. Since that rlib appears first in the linker arguments, its + // symbols are used instead of `libcompiler-rt.a`'s. + if compiler.stage == 0 { + let rtlib = &staticlib("compiler-rt", target); + let src = build.rustc.parent().unwrap().parent().unwrap().join("lib").join("rustlib") + .join(target).join("lib").join(rtlib); + copy(&src, &libdir.join(rtlib)); + } // Some platforms have startup objects that may be required to produce the // libstd dynamic library, for example. @@ -83,12 +93,10 @@ pub fn std_link(build: &Build, // If we're linking one compiler host's output into another, then we weren't // called from the `std` method above. In that case we clean out what's - // already there and then also link compiler-rt into place. + // already there. if host != compiler.host { let _ = fs::remove_dir_all(&libdir); t!(fs::create_dir_all(&libdir)); - copy(&build.compiler_rt_built.borrow()[target], - &libdir.join(staticlib("compiler-rt", target))); } add_to_sysroot(&out_dir, &libdir); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 94c14f7ea25..4beba5c8852 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -28,7 +28,6 @@ extern crate rustc_serialize; extern crate toml; extern crate regex; -use std::cell::RefCell; use std::collections::HashMap; use std::env; use std::fs::{self, File}; @@ -131,7 +130,6 @@ pub struct Build { // Runtime state filled in later on cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>, cxx: HashMap<String, gcc::Tool>, - compiler_rt_built: RefCell<HashMap<String, PathBuf>>, } /// The various "modes" of invoking Cargo. @@ -198,7 +196,6 @@ impl Build { package_vers: String::new(), cc: HashMap::new(), cxx: HashMap::new(), - compiler_rt_built: RefCell::new(HashMap::new()), gdb_version: None, lldb_version: None, lldb_python_dir: None, @@ -252,9 +249,6 @@ impl Build { Llvm { _dummy } => { native::llvm(self, target.target); } - CompilerRt { _dummy } => { - native::compiler_rt(self, target.target); - } TestHelpers { _dummy } => { native::test_helpers(self, target.target); } @@ -839,11 +833,6 @@ impl Build { } } - /// Root output directory for compiler-rt compiled for `target` - fn compiler_rt_out(&self, target: &str) -> PathBuf { - self.out.join(target).join("compiler-rt") - } - /// Root output directory for rust_test_helpers library compiled for /// `target` fn test_helpers_out(&self, target: &str) -> PathBuf { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index a4518d6ed76..df6408e5fe1 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -27,7 +27,7 @@ use cmake; use gcc; use Build; -use util::{staticlib, up_to_date}; +use util::up_to_date; /// Compile LLVM for `target`. pub fn llvm(build: &Build, target: &str) { @@ -131,401 +131,6 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) { panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version) } -/// Compiles the `compiler-rt` library, or at least the builtins part of it. -/// -/// Note that while compiler-rt has a build system associated with it, we -/// specifically don't use it here. The compiler-rt build system, written in -/// CMake, is actually *very* difficult to work with in terms of getting it to -/// compile on all the relevant platforms we want it to compile on. In the end -/// it became so much pain to work with local patches, work around the oddities -/// of the build system, etc, that we're just building everything by hand now. -/// -/// In general compiler-rt is just a bunch of intrinsics that are in practice -/// *very* stable. We just need to make sure that all the relevant functions and -/// such are compiled somewhere and placed in an object file somewhere. -/// Eventually, these should all be written in Rust! -/// -/// So below you'll find a listing of every single file in the compiler-rt repo -/// that we're compiling. We just reach in and compile with the `gcc` crate -/// which should have all the relevant flags and such already configured. -/// -/// The risk here is that if we update compiler-rt we may need to compile some -/// new intrinsics, but to be honest we surely don't use all of the intrinsics -/// listed below today so the likelihood of us actually needing a new intrinsic -/// is quite low. The failure case is also just that someone reports a link -/// error (if any) and then we just add it to the list. Overall, that cost is -/// far far less than working with compiler-rt's build system over time. -pub fn compiler_rt(build: &Build, target: &str) { - let build_dir = build.compiler_rt_out(target); - let output = build_dir.join(staticlib("compiler-rt", target)); - build.compiler_rt_built.borrow_mut().insert(target.to_string(), - output.clone()); - t!(fs::create_dir_all(&build_dir)); - - let mut cfg = gcc::Config::new(); - cfg.cargo_metadata(false) - .out_dir(&build_dir) - .target(target) - .host(&build.config.build) - .opt_level(2) - .debug(false); - - if target.contains("msvc") { - // Don't pull in extra libraries on MSVC - cfg.flag("/Zl"); - - // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP - cfg.define("__func__", Some("__FUNCTION__")); - } else { - // Turn off various features of gcc and such, mostly copying - // compiler-rt's build system already - cfg.flag("-fno-builtin"); - cfg.flag("-fvisibility=hidden"); - cfg.flag("-fomit-frame-pointer"); - cfg.flag("-ffreestanding"); - } - - let mut sources = vec![ - "absvdi2.c", - "absvsi2.c", - "adddf3.c", - "addsf3.c", - "addvdi3.c", - "addvsi3.c", - "apple_versioning.c", - "ashldi3.c", - "ashrdi3.c", - "clear_cache.c", - "clzdi2.c", - "clzsi2.c", - "cmpdi2.c", - "comparedf2.c", - "comparesf2.c", - "ctzdi2.c", - "ctzsi2.c", - "divdc3.c", - "divdf3.c", - "divdi3.c", - "divmoddi4.c", - "divmodsi4.c", - "divsc3.c", - "divsf3.c", - "divsi3.c", - "divxc3.c", - "extendsfdf2.c", - "extendhfsf2.c", - "ffsdi2.c", - "fixdfdi.c", - "fixdfsi.c", - "fixsfdi.c", - "fixsfsi.c", - "fixunsdfdi.c", - "fixunsdfsi.c", - "fixunssfdi.c", - "fixunssfsi.c", - "fixunsxfdi.c", - "fixunsxfsi.c", - "fixxfdi.c", - "floatdidf.c", - "floatdisf.c", - "floatdixf.c", - "floatsidf.c", - "floatsisf.c", - "floatundidf.c", - "floatundisf.c", - "floatundixf.c", - "floatunsidf.c", - "floatunsisf.c", - "int_util.c", - "lshrdi3.c", - "moddi3.c", - "modsi3.c", - "muldc3.c", - "muldf3.c", - "muldi3.c", - "mulodi4.c", - "mulosi4.c", - "muloti4.c", - "mulsc3.c", - "mulsf3.c", - "mulvdi3.c", - "mulvsi3.c", - "mulxc3.c", - "negdf2.c", - "negdi2.c", - "negsf2.c", - "negvdi2.c", - "negvsi2.c", - "paritydi2.c", - "paritysi2.c", - "popcountdi2.c", - "popcountsi2.c", - "powidf2.c", - "powisf2.c", - "powixf2.c", - "subdf3.c", - "subsf3.c", - "subvdi3.c", - "subvsi3.c", - "truncdfhf2.c", - "truncdfsf2.c", - "truncsfhf2.c", - "ucmpdi2.c", - "udivdi3.c", - "udivmoddi4.c", - "udivmodsi4.c", - "udivsi3.c", - "umoddi3.c", - "umodsi3.c", - ]; - - if !target.contains("ios") { - sources.extend(vec![ - "absvti2.c", - "addtf3.c", - "addvti3.c", - "ashlti3.c", - "ashrti3.c", - "clzti2.c", - "cmpti2.c", - "ctzti2.c", - "divtf3.c", - "divti3.c", - "ffsti2.c", - "fixdfti.c", - "fixsfti.c", - "fixunsdfti.c", - "fixunssfti.c", - "fixunsxfti.c", - "fixxfti.c", - "floattidf.c", - "floattisf.c", - "floattixf.c", - "floatuntidf.c", - "floatuntisf.c", - "floatuntixf.c", - "lshrti3.c", - "modti3.c", - "multf3.c", - "multi3.c", - "mulvti3.c", - "negti2.c", - "negvti2.c", - "parityti2.c", - "popcountti2.c", - "powitf2.c", - "subtf3.c", - "subvti3.c", - "trampoline_setup.c", - "ucmpti2.c", - "udivmodti4.c", - "udivti3.c", - "umodti3.c", - ]); - } - - if target.contains("apple") { - sources.extend(vec![ - "atomic_flag_clear.c", - "atomic_flag_clear_explicit.c", - "atomic_flag_test_and_set.c", - "atomic_flag_test_and_set_explicit.c", - "atomic_signal_fence.c", - "atomic_thread_fence.c", - ]); - } - - if !target.contains("windows") { - sources.push("emutls.c"); - } - - if target.contains("msvc") { - if target.contains("x86_64") { - sources.extend(vec![ - "x86_64/floatdidf.c", - "x86_64/floatdisf.c", - "x86_64/floatdixf.c", - ]); - } - } else { - if !target.contains("freebsd") { - sources.push("gcc_personality_v0.c"); - } - - if target.contains("x86_64") { - sources.extend(vec![ - "x86_64/chkstk.S", - "x86_64/chkstk2.S", - "x86_64/floatdidf.c", - "x86_64/floatdisf.c", - "x86_64/floatdixf.c", - "x86_64/floatundidf.S", - "x86_64/floatundisf.S", - "x86_64/floatundixf.S", - ]); - } - - if target.contains("i386") || - target.contains("i586") || - target.contains("i686") { - sources.extend(vec![ - "i386/ashldi3.S", - "i386/ashrdi3.S", - "i386/chkstk.S", - "i386/chkstk2.S", - "i386/divdi3.S", - "i386/floatdidf.S", - "i386/floatdisf.S", - "i386/floatdixf.S", - "i386/floatundidf.S", - "i386/floatundisf.S", - "i386/floatundixf.S", - "i386/lshrdi3.S", - "i386/moddi3.S", - "i386/muldi3.S", - "i386/udivdi3.S", - "i386/umoddi3.S", - ]); - } - } - - if target.contains("arm") && !target.contains("ios") { - sources.extend(vec![ - "arm/aeabi_cdcmp.S", - "arm/aeabi_cdcmpeq_check_nan.c", - "arm/aeabi_cfcmp.S", - "arm/aeabi_cfcmpeq_check_nan.c", - "arm/aeabi_dcmp.S", - "arm/aeabi_div0.c", - "arm/aeabi_drsub.c", - "arm/aeabi_fcmp.S", - "arm/aeabi_frsub.c", - "arm/aeabi_idivmod.S", - "arm/aeabi_ldivmod.S", - "arm/aeabi_memcmp.S", - "arm/aeabi_memcpy.S", - "arm/aeabi_memmove.S", - "arm/aeabi_memset.S", - "arm/aeabi_uidivmod.S", - "arm/aeabi_uldivmod.S", - "arm/bswapdi2.S", - "arm/bswapsi2.S", - "arm/clzdi2.S", - "arm/clzsi2.S", - "arm/comparesf2.S", - "arm/divmodsi4.S", - "arm/divsi3.S", - "arm/modsi3.S", - "arm/switch16.S", - "arm/switch32.S", - "arm/switch8.S", - "arm/switchu8.S", - "arm/sync_synchronize.S", - "arm/udivmodsi4.S", - "arm/udivsi3.S", - "arm/umodsi3.S", - ]); - } - - if target.contains("armv7") { - sources.extend(vec![ - "arm/sync_fetch_and_add_4.S", - "arm/sync_fetch_and_add_8.S", - "arm/sync_fetch_and_and_4.S", - "arm/sync_fetch_and_and_8.S", - "arm/sync_fetch_and_max_4.S", - "arm/sync_fetch_and_max_8.S", - "arm/sync_fetch_and_min_4.S", - "arm/sync_fetch_and_min_8.S", - "arm/sync_fetch_and_nand_4.S", - "arm/sync_fetch_and_nand_8.S", - "arm/sync_fetch_and_or_4.S", - "arm/sync_fetch_and_or_8.S", - "arm/sync_fetch_and_sub_4.S", - "arm/sync_fetch_and_sub_8.S", - "arm/sync_fetch_and_umax_4.S", - "arm/sync_fetch_and_umax_8.S", - "arm/sync_fetch_and_umin_4.S", - "arm/sync_fetch_and_umin_8.S", - "arm/sync_fetch_and_xor_4.S", - "arm/sync_fetch_and_xor_8.S", - ]); - } - - if target.contains("eabihf") { - sources.extend(vec![ - "arm/adddf3vfp.S", - "arm/addsf3vfp.S", - "arm/divdf3vfp.S", - "arm/divsf3vfp.S", - "arm/eqdf2vfp.S", - "arm/eqsf2vfp.S", - "arm/extendsfdf2vfp.S", - "arm/fixdfsivfp.S", - "arm/fixsfsivfp.S", - "arm/fixunsdfsivfp.S", - "arm/fixunssfsivfp.S", - "arm/floatsidfvfp.S", - "arm/floatsisfvfp.S", - "arm/floatunssidfvfp.S", - "arm/floatunssisfvfp.S", - "arm/gedf2vfp.S", - "arm/gesf2vfp.S", - "arm/gtdf2vfp.S", - "arm/gtsf2vfp.S", - "arm/ledf2vfp.S", - "arm/lesf2vfp.S", - "arm/ltdf2vfp.S", - "arm/ltsf2vfp.S", - "arm/muldf3vfp.S", - "arm/mulsf3vfp.S", - "arm/negdf2vfp.S", - "arm/negsf2vfp.S", - "arm/nedf2vfp.S", - "arm/nesf2vfp.S", - "arm/restore_vfp_d8_d15_regs.S", - "arm/save_vfp_d8_d15_regs.S", - "arm/subdf3vfp.S", - "arm/subsf3vfp.S", - "arm/truncdfsf2vfp.S", - "arm/unorddf2vfp.S", - "arm/unordsf2vfp.S", - ]); - } - - if target.contains("aarch64") { - sources.extend(vec![ - "comparetf2.c", - "extenddftf2.c", - "extendsftf2.c", - "fixtfdi.c", - "fixtfsi.c", - "fixtfti.c", - "fixunstfdi.c", - "fixunstfsi.c", - "fixunstfti.c", - "floatditf.c", - "floatsitf.c", - "floatunditf.c", - "floatunsitf.c", - "multc3.c", - "trunctfdf2.c", - "trunctfsf2.c", - ]); - } - - let mut out_of_date = false; - for src in sources { - let src = build.src.join("src/compiler-rt/lib/builtins").join(src); - out_of_date = out_of_date || !up_to_date(&src, &output); - cfg.file(src); - } - if !out_of_date { - return - } - cfg.compile("libcompiler-rt.a"); -} - /// Compiles the `rust_test_helpers.c` library which we used in various /// `run-pass` test suites for ABI testing. pub fn test_helpers(build: &Build, target: &str) { diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 12929664886..5f391b70fbe 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -82,7 +82,6 @@ macro_rules! targets { // There aren't really any parameters to this, but empty structs // with braces are unstable so we just pick something that works. (llvm, Llvm { _dummy: () }), - (compiler_rt, CompilerRt { _dummy: () }), (test_helpers, TestHelpers { _dummy: () }), (debugger_scripts, DebuggerScripts { stage: u32 }), @@ -334,8 +333,7 @@ impl<'a> Step<'a> { vec![self.libstd(compiler)] } Source::Libstd { compiler } => { - vec![self.compiler_rt(()), - self.rustc(compiler.stage).target(compiler.host)] + vec![self.rustc(compiler.stage).target(compiler.host)] } Source::LibrustcLink { compiler, host } => { vec![self.librustc(compiler), @@ -348,7 +346,6 @@ impl<'a> Step<'a> { vec![self.libstd(compiler), self.target(host).rustc(compiler.stage)] } - Source::CompilerRt { _dummy } => Vec::new(), Source::Llvm { _dummy } => Vec::new(), Source::TestHelpers { _dummy } => Vec::new(), Source::DebuggerScripts { stage: _ } => Vec::new(), diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index dfc1c7a243b..6c0a32a54d9 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -23,7 +23,7 @@ use filetime::FileTime; /// Returns the `name` as the filename of a static library for `target`. pub fn staticlib(name: &str, target: &str) -> String { - if target.contains("windows-msvc") { + if target.contains("windows") { format!("{}.lib", name) } else { format!("lib{}.a", name) diff --git a/src/libcompiler_builtins/Cargo.toml b/src/libcompiler_builtins/Cargo.toml new file mode 100644 index 00000000000..a52873fc326 --- /dev/null +++ b/src/libcompiler_builtins/Cargo.toml @@ -0,0 +1,15 @@ +[package] +authors = ["The Rust Project Developers"] +build = "build.rs" +name = "compiler_builtins" +version = "0.0.0" + +[lib] +name = "compiler_builtins" +path = "lib.rs" + +[dependencies] +core = { path = "../libcore" } + +[build-dependencies] +gcc = "0.3.27" diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs new file mode 100644 index 00000000000..09c400b52bc --- /dev/null +++ b/src/libcompiler_builtins/build.rs @@ -0,0 +1,404 @@ +// 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. + +//! Compiles the `compiler-rt` library, or at least the builtins part of it. +//! +//! Note that while compiler-rt has a build system associated with it, we +//! specifically don't use it here. The compiler-rt build system, written in +//! CMake, is actually *very* difficult to work with in terms of getting it to +//! compile on all the relevant platforms we want it to compile on. In the end +//! it became so much pain to work with local patches, work around the oddities +//! of the build system, etc, that we're just building everything by hand now. +//! +//! In general compiler-rt is just a bunch of intrinsics that are in practice +//! *very* stable. We just need to make sure that all the relevant functions and +//! such are compiled somewhere and placed in an object file somewhere. +//! Eventually, these should all be written in Rust! +//! +//! So below you'll find a listing of every single file in the compiler-rt repo +//! that we're compiling. We just reach in and compile with the `gcc` crate +//! which should have all the relevant flags and such already configured. +//! +//! The risk here is that if we update compiler-rt we may need to compile some +//! new intrinsics, but to be honest we surely don't use all of the intrinsics +//! listed below today so the likelihood of us actually needing a new intrinsic +//! is quite low. The failure case is also just that someone reports a link +//! error (if any) and then we just add it to the list. Overall, that cost is +//! far far less than working with compiler-rt's build system over time. + +extern crate gcc; + +use std::collections::BTreeMap; +use std::env; +use std::path::Path; + +struct Sources { + // SYMBOL -> PATH TO SOURCE + map: BTreeMap<&'static str, &'static str>, +} + +impl Sources { + fn new() -> Sources { + Sources { map: BTreeMap::new() } + } + + fn extend(&mut self, sources: &[&'static str]) { + // NOTE Some intrinsics have both a generic implementation (e.g. + // `floatdidf.c`) and an arch optimized implementation + // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized + // implementation and discard the generic implementation. If we don't + // and keep both implementations, the linker will yell at us about + // duplicate symbols! + for &src in sources { + let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap(); + if src.contains("/") { + // Arch-optimized implementation (preferred) + self.map.insert(symbol, src); + } else { + // Generic implementation + if !self.map.contains_key(symbol) { + self.map.insert(symbol, src); + } + } + } + } +} + +fn main() { + let target = env::var("TARGET").unwrap(); + let cfg = &mut gcc::Config::new(); + + if target.contains("msvc") { + // Don't pull in extra libraries on MSVC + cfg.flag("/Zl"); + + // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP + cfg.define("__func__", Some("__FUNCTION__")); + } else { + // Turn off various features of gcc and such, mostly copying + // compiler-rt's build system already + cfg.flag("-fno-builtin"); + cfg.flag("-fvisibility=hidden"); + cfg.flag("-fomit-frame-pointer"); + cfg.flag("-ffreestanding"); + } + + let mut sources = Sources::new(); + sources.extend(&["absvdi2.c", + "absvsi2.c", + "adddf3.c", + "addsf3.c", + "addvdi3.c", + "addvsi3.c", + "apple_versioning.c", + "ashldi3.c", + "ashrdi3.c", + "clear_cache.c", + "clzdi2.c", + "clzsi2.c", + "cmpdi2.c", + "comparedf2.c", + "comparesf2.c", + "ctzdi2.c", + "ctzsi2.c", + "divdc3.c", + "divdf3.c", + "divdi3.c", + "divmoddi4.c", + "divmodsi4.c", + "divsc3.c", + "divsf3.c", + "divsi3.c", + "divxc3.c", + "extendsfdf2.c", + "extendhfsf2.c", + "ffsdi2.c", + "fixdfdi.c", + "fixdfsi.c", + "fixsfdi.c", + "fixsfsi.c", + "fixunsdfdi.c", + "fixunsdfsi.c", + "fixunssfdi.c", + "fixunssfsi.c", + "fixunsxfdi.c", + "fixunsxfsi.c", + "fixxfdi.c", + "floatdidf.c", + "floatdisf.c", + "floatdixf.c", + "floatsidf.c", + "floatsisf.c", + "floatundidf.c", + "floatundisf.c", + "floatundixf.c", + "floatunsidf.c", + "floatunsisf.c", + "int_util.c", + "lshrdi3.c", + "moddi3.c", + "modsi3.c", + "muldc3.c", + "muldf3.c", + "muldi3.c", + "mulodi4.c", + "mulosi4.c", + "muloti4.c", + "mulsc3.c", + "mulsf3.c", + "mulvdi3.c", + "mulvsi3.c", + "mulxc3.c", + "negdf2.c", + "negdi2.c", + "negsf2.c", + "negvdi2.c", + "negvsi2.c", + "paritydi2.c", + "paritysi2.c", + "popcountdi2.c", + "popcountsi2.c", + "powidf2.c", + "powisf2.c", + "powixf2.c", + "subdf3.c", + "subsf3.c", + "subvdi3.c", + "subvsi3.c", + "truncdfhf2.c", + "truncdfsf2.c", + "truncsfhf2.c", + "ucmpdi2.c", + "udivdi3.c", + "udivmoddi4.c", + "udivmodsi4.c", + "udivsi3.c", + "umoddi3.c", + "umodsi3.c"]); + + if !target.contains("ios") { + sources.extend(&["absvti2.c", + "addtf3.c", + "addvti3.c", + "ashlti3.c", + "ashrti3.c", + "clzti2.c", + "cmpti2.c", + "ctzti2.c", + "divtf3.c", + "divti3.c", + "ffsti2.c", + "fixdfti.c", + "fixsfti.c", + "fixunsdfti.c", + "fixunssfti.c", + "fixunsxfti.c", + "fixxfti.c", + "floattidf.c", + "floattisf.c", + "floattixf.c", + "floatuntidf.c", + "floatuntisf.c", + "floatuntixf.c", + "lshrti3.c", + "modti3.c", + "multf3.c", + "multi3.c", + "mulvti3.c", + "negti2.c", + "negvti2.c", + "parityti2.c", + "popcountti2.c", + "powitf2.c", + "subtf3.c", + "subvti3.c", + "trampoline_setup.c", + "ucmpti2.c", + "udivmodti4.c", + "udivti3.c", + "umodti3.c"]); + } + + if target.contains("apple") { + sources.extend(&["atomic_flag_clear.c", + "atomic_flag_clear_explicit.c", + "atomic_flag_test_and_set.c", + "atomic_flag_test_and_set_explicit.c", + "atomic_signal_fence.c", + "atomic_thread_fence.c"]); + } + + if !target.contains("windows") { + sources.extend(&["emutls.c"]); + } + + if target.contains("msvc") { + if target.contains("x86_64") { + sources.extend(&["x86_64/floatdidf.c", "x86_64/floatdisf.c", "x86_64/floatdixf.c"]); + } + } else { + if !target.contains("freebsd") { + sources.extend(&["gcc_personality_v0.c"]); + } + + if target.contains("x86_64") { + sources.extend(&["x86_64/chkstk.S", + "x86_64/chkstk2.S", + "x86_64/floatdidf.c", + "x86_64/floatdisf.c", + "x86_64/floatdixf.c", + "x86_64/floatundidf.S", + "x86_64/floatundisf.S", + "x86_64/floatundixf.S"]); + } + + if target.contains("i386") || target.contains("i586") || target.contains("i686") { + sources.extend(&["i386/ashldi3.S", + "i386/ashrdi3.S", + "i386/chkstk.S", + "i386/chkstk2.S", + "i386/divdi3.S", + "i386/floatdidf.S", + "i386/floatdisf.S", + "i386/floatdixf.S", + "i386/floatundidf.S", + "i386/floatundisf.S", + "i386/floatundixf.S", + "i386/lshrdi3.S", + "i386/moddi3.S", + "i386/muldi3.S", + "i386/udivdi3.S", + "i386/umoddi3.S"]); + } + } + + if target.contains("arm") && !target.contains("ios") { + sources.extend(&["arm/aeabi_cdcmp.S", + "arm/aeabi_cdcmpeq_check_nan.c", + "arm/aeabi_cfcmp.S", + "arm/aeabi_cfcmpeq_check_nan.c", + "arm/aeabi_dcmp.S", + "arm/aeabi_div0.c", + "arm/aeabi_drsub.c", + "arm/aeabi_fcmp.S", + "arm/aeabi_frsub.c", + "arm/aeabi_idivmod.S", + "arm/aeabi_ldivmod.S", + "arm/aeabi_memcmp.S", + "arm/aeabi_memcpy.S", + "arm/aeabi_memmove.S", + "arm/aeabi_memset.S", + "arm/aeabi_uidivmod.S", + "arm/aeabi_uldivmod.S", + "arm/bswapdi2.S", + "arm/bswapsi2.S", + "arm/clzdi2.S", + "arm/clzsi2.S", + "arm/comparesf2.S", + "arm/divmodsi4.S", + "arm/divsi3.S", + "arm/modsi3.S", + "arm/switch16.S", + "arm/switch32.S", + "arm/switch8.S", + "arm/switchu8.S", + "arm/sync_synchronize.S", + "arm/udivmodsi4.S", + "arm/udivsi3.S", + "arm/umodsi3.S"]); + } + + if target.contains("armv7") { + sources.extend(&["arm/sync_fetch_and_add_4.S", + "arm/sync_fetch_and_add_8.S", + "arm/sync_fetch_and_and_4.S", + "arm/sync_fetch_and_and_8.S", + "arm/sync_fetch_and_max_4.S", + "arm/sync_fetch_and_max_8.S", + "arm/sync_fetch_and_min_4.S", + "arm/sync_fetch_and_min_8.S", + "arm/sync_fetch_and_nand_4.S", + "arm/sync_fetch_and_nand_8.S", + "arm/sync_fetch_and_or_4.S", + "arm/sync_fetch_and_or_8.S", + "arm/sync_fetch_and_sub_4.S", + "arm/sync_fetch_and_sub_8.S", + "arm/sync_fetch_and_umax_4.S", + "arm/sync_fetch_and_umax_8.S", + "arm/sync_fetch_and_umin_4.S", + "arm/sync_fetch_and_umin_8.S", + "arm/sync_fetch_and_xor_4.S", + "arm/sync_fetch_and_xor_8.S"]); + } + + if target.contains("eabihf") { + sources.extend(&["arm/adddf3vfp.S", + "arm/addsf3vfp.S", + "arm/divdf3vfp.S", + "arm/divsf3vfp.S", + "arm/eqdf2vfp.S", + "arm/eqsf2vfp.S", + "arm/extendsfdf2vfp.S", + "arm/fixdfsivfp.S", + "arm/fixsfsivfp.S", + "arm/fixunsdfsivfp.S", + "arm/fixunssfsivfp.S", + "arm/floatsidfvfp.S", + "arm/floatsisfvfp.S", + "arm/floatunssidfvfp.S", + "arm/floatunssisfvfp.S", + "arm/gedf2vfp.S", + "arm/gesf2vfp.S", + "arm/gtdf2vfp.S", + "arm/gtsf2vfp.S", + "arm/ledf2vfp.S", + "arm/lesf2vfp.S", + "arm/ltdf2vfp.S", + "arm/ltsf2vfp.S", + "arm/muldf3vfp.S", + "arm/mulsf3vfp.S", + "arm/negdf2vfp.S", + "arm/negsf2vfp.S", + "arm/nedf2vfp.S", + "arm/nesf2vfp.S", + "arm/restore_vfp_d8_d15_regs.S", + "arm/save_vfp_d8_d15_regs.S", + "arm/subdf3vfp.S", + "arm/subsf3vfp.S", + "arm/truncdfsf2vfp.S", + "arm/unorddf2vfp.S", + "arm/unordsf2vfp.S"]); + } + + if target.contains("aarch64") { + sources.extend(&["comparetf2.c", + "extenddftf2.c", + "extendsftf2.c", + "fixtfdi.c", + "fixtfsi.c", + "fixtfti.c", + "fixunstfdi.c", + "fixunstfsi.c", + "fixunstfti.c", + "floatditf.c", + "floatsitf.c", + "floatunditf.c", + "floatunsitf.c", + "multc3.c", + "trunctfdf2.c", + "trunctfsf2.c"]); + } + + for src in sources.map.values() { + cfg.file(Path::new("../compiler-rt/lib/builtins").join(src)); + } + + cfg.compile("libcompiler-rt.a"); +} diff --git a/src/libcompiler_builtins/lib.rs b/src/libcompiler_builtins/lib.rs new file mode 100644 index 00000000000..fbcf5204d25 --- /dev/null +++ b/src/libcompiler_builtins/lib.rs @@ -0,0 +1,19 @@ +// 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(compiler_builtins))] +#![no_std] +#![cfg_attr(not(stage0), compiler_builtins)] +#![unstable(feature = "compiler_builtins_lib", + reason = "internal implementation detail of rustc right now", + issue = "0")] +#![crate_name = "compiler_builtins"] +#![crate_type = "rlib"] +#![feature(staged_api)] diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index d1722ac6f2f..b8465e63b1c 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -210,6 +210,7 @@ pub trait CrateStore<'tcx> { fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool; fn is_allocator(&self, cnum: ast::CrateNum) -> bool; fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool; + fn is_compiler_builtins(&self, cnum: ast::CrateNum) -> bool; fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy; fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate>; fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>; @@ -405,6 +406,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool { bug!("is_explicitly_linked") } fn is_allocator(&self, cnum: ast::CrateNum) -> bool { bug!("is_allocator") } fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool { bug!("is_panic_runtime") } + fn is_compiler_builtins(&self, cnum: ast::CrateNum) -> bool { bug!("is_compiler_builtins") } fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy { bug!("panic_strategy") } diff --git a/src/librustc_back/target/asmjs_unknown_emscripten.rs b/src/librustc_back/target/asmjs_unknown_emscripten.rs index 07eb191471c..9ccfdbb129c 100644 --- a/src/librustc_back/target/asmjs_unknown_emscripten.rs +++ b/src/librustc_back/target/asmjs_unknown_emscripten.rs @@ -18,7 +18,6 @@ pub fn target() -> Result<Target, String> { dynamic_linking: false, executables: true, exe_suffix: ".js".to_string(), - no_compiler_rt: true, linker_is_gnu: true, allow_asm: false, obj_is_bitcode: true, diff --git a/src/librustc_back/target/le32_unknown_nacl.rs b/src/librustc_back/target/le32_unknown_nacl.rs index 25132f8a044..9ba6591f587 100644 --- a/src/librustc_back/target/le32_unknown_nacl.rs +++ b/src/librustc_back/target/le32_unknown_nacl.rs @@ -22,7 +22,6 @@ pub fn target() -> TargetResult { dynamic_linking: false, executables: true, exe_suffix: ".pexe".to_string(), - no_compiler_rt: false, linker_is_gnu: true, allow_asm: false, max_atomic_width: 32, diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index d48370b23b6..1a26ffaf1e1 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -306,9 +306,6 @@ pub struct TargetOptions { pub allows_weak_linkage: bool, /// Whether the linker support rpaths or not. Defaults to false. pub has_rpath: bool, - /// Whether to disable linking to compiler-rt. Defaults to false, as LLVM - /// will emit references to the functions that compiler-rt provides. - pub no_compiler_rt: bool, /// Whether to disable linking to the default libraries, typically corresponds /// to `-nodefaultlibs`. Defaults to true. pub no_default_libraries: bool, @@ -381,7 +378,6 @@ impl Default for TargetOptions { linker_is_gnu: false, allows_weak_linkage: true, has_rpath: false, - no_compiler_rt: false, no_default_libraries: true, position_independent_executables: false, pre_link_objects_exe: Vec::new(), @@ -524,7 +520,6 @@ impl Target { key!(linker_is_gnu, bool); key!(allows_weak_linkage, bool); key!(has_rpath, bool); - key!(no_compiler_rt, bool); key!(no_default_libraries, bool); key!(position_independent_executables, bool); key!(archive_format); @@ -667,7 +662,6 @@ impl ToJson for Target { target_option_val!(linker_is_gnu); target_option_val!(allows_weak_linkage); target_option_val!(has_rpath); - target_option_val!(no_compiler_rt); target_option_val!(no_default_libraries); target_option_val!(position_independent_executables); target_option_val!(archive_format); diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index d7ca93235fd..21cf3240321 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -346,6 +346,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(cnum).is_panic_runtime() } + fn is_compiler_builtins(&self, cnum: ast::CrateNum) -> bool { + self.get_crate_data(cnum).is_compiler_builtins() + } + fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy { self.get_crate_data(cnum).panic_strategy() } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 952d7008d0f..bc3d92c11a1 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -340,6 +340,11 @@ impl CrateMetadata { attr::contains_name(&attrs, "needs_panic_runtime") } + pub fn is_compiler_builtins(&self) -> bool { + let attrs = decoder::get_crate_attributes(self.data()); + attr::contains_name(&attrs, "compiler_builtins") + } + pub fn panic_strategy(&self) -> PanicStrategy { decoder::get_panic_strategy(self.data()) } diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index b970c63a224..288249a7d99 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -573,10 +573,6 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write, fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path, tempdir: &Path) { let mut ab = link_rlib(sess, None, objects, out_filename, tempdir); - if !sess.target.target.options.no_compiler_rt { - ab.add_native_library("compiler-rt"); - } - let mut all_native_libs = vec![]; each_linked_rlib(sess, &mut |cnum, path| { @@ -640,9 +636,6 @@ fn link_natively(sess: &Session, let mut linker = trans.linker_info.to_linker(&mut cmd, &sess); link_args(&mut *linker, sess, crate_type, tmpdir, objects, out_filename, outputs); - if !sess.target.target.options.no_compiler_rt { - linker.link_staticlib("compiler-rt"); - } } cmd.args(&sess.target.target.options.late_link_args); for obj in &sess.target.target.options.post_link_objects { @@ -933,17 +926,24 @@ fn add_upstream_rust_crates(cmd: &mut Linker, // crates. let deps = sess.cstore.used_crates(LinkagePreference::RequireDynamic); + let mut compiler_builtins = None; + for &(cnum, _) in &deps { // We may not pass all crates through to the linker. Some crates may // appear statically in an existing dylib, meaning we'll pick up all the // symbols from the dylib. let src = sess.cstore.used_crate_source(cnum); match data[cnum as usize - 1] { + // compiler-builtins are always placed last to ensure that they're + // linked correctly. + _ if sess.cstore.is_compiler_builtins(cnum) => { + assert!(compiler_builtins.is_none()); + compiler_builtins = Some(cnum); + } Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => { - add_static_crate(cmd, sess, tmpdir, crate_type, - &src.rlib.unwrap().0, sess.cstore.is_no_builtins(cnum)) + add_static_crate(cmd, sess, tmpdir, crate_type, cnum); } Linkage::Dynamic => { add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0) @@ -951,6 +951,13 @@ fn add_upstream_rust_crates(cmd: &mut Linker, } } + // 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) + if let Some(cnum) = compiler_builtins { + add_static_crate(cmd, sess, tmpdir, crate_type, cnum); + } + // Converts a library file-stem into a cc -l argument fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str { if stem.starts_with("lib") && !config.target.options.is_like_windows { @@ -996,8 +1003,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session, tmpdir: &Path, crate_type: config::CrateType, - cratepath: &Path, - is_a_no_builtins_crate: bool) { + cnum: ast::CrateNum) { + let src = sess.cstore.used_crate_source(cnum); + let cratepath = &src.rlib.unwrap().0; if !sess.lto() && crate_type != config::CrateTypeDylib { cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath)); return @@ -1021,7 +1029,13 @@ fn add_upstream_rust_crates(cmd: &mut Linker, } let canonical = f.replace("-", "_"); let canonical_name = name.replace("-", "_"); - if sess.lto() && !is_a_no_builtins_crate && + + // If we're performing LTO and this is a rust-generated object + // file, then we don't need the object file as it's part of the + // LTO module. Note that `#![no_builtins]` is excluded from LTO, + // though, so we let that object file slide. + if sess.lto() && + !sess.cstore.is_no_builtins(cnum) && canonical.starts_with(&canonical_name) && canonical.ends_with(".o") { let num = &f[name.len()..f.len() - 2]; @@ -1033,13 +1047,23 @@ fn add_upstream_rust_crates(cmd: &mut Linker, any_objects = true; } - if any_objects { - archive.build(); - if crate_type == config::CrateTypeDylib { - cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst)); - } else { - cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst)); - } + if !any_objects { + return + } + archive.build(); + + // If we're creating a dylib, then we need to include the + // whole of each object in our archive into that artifact. This is + // because a `dylib` can be reused as an intermediate artifact. + // + // Note, though, that we don't want to include the whole of a + // compiler-builtins crate (e.g. compiler-rt) because it'll get + // repeatedly linked anyway. + if crate_type == config::CrateTypeDylib && + !sess.cstore.is_compiler_builtins(cnum) { + cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst)); + } else { + cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst)); } }); } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 3ce6841fdd4..21e6acc37f3 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -19,6 +19,7 @@ collections = { path = "../libcollections" } core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } rand = { path = "../librand" } +compiler_builtins = { path = "../libcompiler_builtins" } rustc_unicode = { path = "../librustc_unicode" } unwind = { path = "../libunwind" } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 4a637b5cfcf..115a24fc83c 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -224,6 +224,7 @@ #![feature(char_internals)] #![feature(collections)] #![feature(collections_bound)] +#![feature(compiler_builtins_lib)] #![feature(const_fn)] #![feature(core_float)] #![feature(core_intrinsics)] @@ -322,6 +323,9 @@ extern crate unwind; #[cfg(stage0)] extern crate alloc_system; +// compiler-rt intrinsics +extern crate compiler_builtins; + // Make std testable by not duplicating lang items and other globals. See #2912 #[cfg(test)] extern crate std as realstd; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 8b8a41fc204..27b97a0ad66 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -298,6 +298,10 @@ declare_features! ( // elide `'static` lifetimes in `static`s and `const`s (active, static_in_const, "1.13.0", Some(35897)), + + // Used to identify the `compiler_builtins` crate + // rustc internal + (active, compiler_builtins, "1.13.0", None), ); declare_features! ( @@ -537,6 +541,12 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat libcore functions that are inlined \ across crates and will never be stable", cfg_fn!(rustc_attrs))), + ("compiler_builtins", Whitelisted, Gated("compiler_builtins", + "the `#[compiler_builtins]` attribute is used to \ + identify the `compiler_builtins` crate which \ + contains compiler-rt intrinsics and will never be \ + stable", + cfg_fn!(compiler_builtins))), ("allow_internal_unstable", Normal, Gated("allow_internal_unstable", EXPLAIN_ALLOW_INTERNAL_UNSTABLE, diff --git a/src/rustc/std_shim/Cargo.lock b/src/rustc/std_shim/Cargo.lock index d47b541b4c3..747322b32f3 100644 --- a/src/rustc/std_shim/Cargo.lock +++ b/src/rustc/std_shim/Cargo.lock @@ -44,6 +44,14 @@ dependencies = [ ] [[package]] +name = "compiler_builtins" +version = "0.0.0" +dependencies = [ + "core 0.0.0", + "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "core" version = "0.0.0" @@ -100,6 +108,7 @@ dependencies = [ "alloc_system 0.0.0", "build_helper 0.1.0", "collections 0.0.0", + "compiler_builtins 0.0.0", "core 0.0.0", "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.0.0", diff --git a/src/test/compile-fail/feature-gate-compiler-builtins.rs b/src/test/compile-fail/feature-gate-compiler-builtins.rs new file mode 100644 index 00000000000..f9334f1d3b0 --- /dev/null +++ b/src/test/compile-fail/feature-gate-compiler-builtins.rs @@ -0,0 +1,14 @@ +// 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. + +#![compiler_builtins] //~ ERROR the `#[compiler_builtins]` attribute is + +fn main() {} + diff --git a/src/test/run-make/no-duplicate-libs/bar.rs b/src/test/run-make/no-duplicate-libs/bar.rs index 8a15afb328a..b82fdeb8f36 100644 --- a/src/test/run-make/no-duplicate-libs/bar.rs +++ b/src/test/run-make/no-duplicate-libs/bar.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, libc)] +#![feature(lang_items, libc, compiler_builtins_lib)] #![crate_type = "dylib"] #![no_std] extern crate libc; +extern crate compiler_builtins; #[no_mangle] pub extern fn bar() {} diff --git a/src/test/run-make/no-duplicate-libs/foo.rs b/src/test/run-make/no-duplicate-libs/foo.rs index ab8d2eca936..cbdee356838 100644 --- a/src/test/run-make/no-duplicate-libs/foo.rs +++ b/src/test/run-make/no-duplicate-libs/foo.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, libc)] +#![feature(lang_items, libc, compiler_builtins_lib)] #![no_std] #![crate_type = "dylib"] extern crate libc; +extern crate compiler_builtins; #[no_mangle] pub extern fn foo() {} |
