From 1516087ca91f0aa8c9f4f8cb0aa6ff48862043c4 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Mon, 29 Apr 2019 16:57:29 -0400 Subject: [PATCH 1/2] add negative tests for OS X LLVM target changes --- .../i686-no-macosx-deployment-target.rs | 26 +++++++++++++++++++ .../x86_64-no-macosx-deployment-target.rs | 26 +++++++++++++++++++ src/tools/compiletest/src/header.rs | 8 ++++++ src/tools/compiletest/src/runtest.rs | 3 +++ 4 files changed, 63 insertions(+) create mode 100644 src/test/codegen/i686-no-macosx-deployment-target.rs create mode 100644 src/test/codegen/x86_64-no-macosx-deployment-target.rs diff --git a/src/test/codegen/i686-no-macosx-deployment-target.rs b/src/test/codegen/i686-no-macosx-deployment-target.rs new file mode 100644 index 00000000000..eb826590523 --- /dev/null +++ b/src/test/codegen/i686-no-macosx-deployment-target.rs @@ -0,0 +1,26 @@ +// +// Checks that we leave the target alone MACOSX_DEPLOYMENT_TARGET is unset. +// See issue #60235. + +// compile-flags: -O --target=i686-apple-darwin --crate-type=rlib +// unset-rustc-env:MACOSX_DEPLOYMENT_TARGET +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="freeze"] +trait Freeze { } +#[lang="copy"] +trait Copy { } + +#[repr(C)] +pub struct Bool { + b: bool, +} + +// CHECK: target triple = "i686-apple-darwin" +#[no_mangle] +pub extern "C" fn structbool() -> Bool { + Bool { b: true } +} diff --git a/src/test/codegen/x86_64-no-macosx-deployment-target.rs b/src/test/codegen/x86_64-no-macosx-deployment-target.rs new file mode 100644 index 00000000000..58a11d1095b --- /dev/null +++ b/src/test/codegen/x86_64-no-macosx-deployment-target.rs @@ -0,0 +1,26 @@ +// +// Checks that we leave the target alone when MACOSX_DEPLOYMENT_TARGET is unset. +// See issue #60235. + +// compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib +// unset-rustc-env:MACOSX_DEPLOYMENT_TARGET +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="freeze"] +trait Freeze { } +#[lang="copy"] +trait Copy { } + +#[repr(C)] +pub struct Bool { + b: bool, +} + +// CHECK: target triple = "x86_64-apple-darwin" +#[no_mangle] +pub extern "C" fn structbool() -> Bool { + Bool { b: true } +} diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index fb6ada89171..54e9b76a21e 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -305,6 +305,9 @@ pub struct TestProps { pub extern_private: Vec, // Environment settings to use for compiling pub rustc_env: Vec<(String, String)>, + // Environment variables to unset prior to compiling. + // Variables are unset before applying 'rustc_env'. + pub unset_rustc_env: Vec, // Environment settings to use during execution pub exec_env: Vec<(String, String)>, // Lines to check if they appear in the expected debugger output @@ -373,6 +376,7 @@ impl TestProps { extern_private: vec![], revisions: vec![], rustc_env: vec![], + unset_rustc_env: vec![], exec_env: vec![], check_lines: vec![], build_aux_docs: false, @@ -499,6 +503,10 @@ impl TestProps { self.rustc_env.push(ee); } + if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") { + self.unset_rustc_env.push(ev); + } + if let Some(cl) = config.parse_check_line(ln) { self.check_lines.push(cl); } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 42f9cdb7886..d3e39867a31 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1692,6 +1692,9 @@ impl<'test> TestCx<'test> { add_extern_priv(&private_lib, true); } + self.props.unset_rustc_env.clone() + .iter() + .fold(&mut rustc, |rustc, v| rustc.env_remove(v)); rustc.envs(self.props.rustc_env.clone()); self.compose_and_run( rustc, From 97ba4c95d00108ac79c86d2bbc6834b1fef008a2 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 25 Apr 2019 16:04:37 -0400 Subject: [PATCH 2/2] choose a more specific LLVM target on OS X when necessary This behavior matches clang's behavior, and makes cross-language LTO possible. Fixes #60235. --- src/librustc_metadata/creader.rs | 4 +-- src/librustc_target/spec/apple_base.rs | 32 +++++++++++++++---- src/librustc_target/spec/i686_apple_darwin.rs | 8 ++++- .../spec/x86_64_apple_darwin.rs | 10 ++++-- .../codegen/i686-macosx-deployment-target.rs | 26 +++++++++++++++ .../x86_64-macosx-deployment-target.rs | 26 +++++++++++++++ 6 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 src/test/codegen/i686-macosx-deployment-target.rs create mode 100644 src/test/codegen/x86_64-macosx-deployment-target.rs diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 160d4c30c0b..c47d7d85a37 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -783,7 +783,7 @@ impl<'a> CrateLoader<'a> { Sanitizer::Leak => LSAN_SUPPORTED_TARGETS, Sanitizer::Memory => MSAN_SUPPORTED_TARGETS, }; - if !supported_targets.contains(&&*self.sess.target.target.llvm_target) { + if !supported_targets.contains(&&*self.sess.opts.target_triple.triple()) { self.sess.err(&format!("{:?}Sanitizer only works with the `{}` target", sanitizer, supported_targets.join("` or `") @@ -794,7 +794,7 @@ impl<'a> CrateLoader<'a> { // firstyear 2017 - during testing I was unable to access an OSX machine // to make this work on different crate types. As a result, today I have // only been able to test and support linux as a target. - if self.sess.target.target.llvm_target == "x86_64-unknown-linux-gnu" { + if self.sess.opts.target_triple.triple() == "x86_64-unknown-linux-gnu" { if !self.sess.crate_types.borrow().iter().all(|ct| { match *ct { // Link the runtime diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs index c21f7f38ca5..9dd343b6c8d 100644 --- a/src/librustc_target/spec/apple_base.rs +++ b/src/librustc_target/spec/apple_base.rs @@ -14,13 +14,7 @@ pub fn opts() -> TargetOptions { // // Here we detect what version is being requested, defaulting to 10.7. ELF // TLS is flagged as enabled if it looks to be supported. - let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok(); - let version = deployment_target.as_ref().and_then(|s| { - let mut i = s.splitn(2, '.'); - i.next().and_then(|a| i.next().map(|b| (a, b))) - }).and_then(|(a, b)| { - a.parse::().and_then(|a| b.parse::().map(|b| (a, b))).ok() - }).unwrap_or((10, 7)); + let version = macos_deployment_target().unwrap_or((10, 7)); TargetOptions { // macOS has -dead_strip, which doesn't rely on function_sections @@ -40,3 +34,27 @@ pub fn opts() -> TargetOptions { .. Default::default() } } + +fn macos_deployment_target() -> Option<(u32, u32)> { + let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok(); + let version = deployment_target.as_ref().and_then(|s| { + let mut i = s.splitn(2, '.'); + i.next().and_then(|a| i.next().map(|b| (a, b))) + }).and_then(|(a, b)| { + a.parse::().and_then(|a| b.parse::().map(|b| (a, b))).ok() + }); + + version +} + +pub fn macos_llvm_target(arch: &str) -> String { + let version = macos_deployment_target(); + let llvm_target = match version { + Some((major, minor)) => { + format!("{}-apple-macosx{}.{}.0", arch, major, minor) + }, + None => format!("{}-apple-darwin", arch) + }; + + llvm_target +} diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs index 58c59cc8728..7d804ea53fb 100644 --- a/src/librustc_target/spec/i686_apple_darwin.rs +++ b/src/librustc_target/spec/i686_apple_darwin.rs @@ -8,8 +8,14 @@ pub fn target() -> TargetResult { base.stack_probes = true; base.eliminate_frame_pointer = false; + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + let arch = "i686"; + let llvm_target = super::apple_base::macos_llvm_target(&arch); + Ok(Target { - llvm_target: "i686-apple-darwin".to_string(), + llvm_target: llvm_target, target_endian: "little".to_string(), target_pointer_width: "32".to_string(), target_c_int_width: "32".to_string(), diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs index c54181741b3..182103440f0 100644 --- a/src/librustc_target/spec/x86_64_apple_darwin.rs +++ b/src/librustc_target/spec/x86_64_apple_darwin.rs @@ -8,13 +8,19 @@ pub fn target() -> TargetResult { base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); base.stack_probes = true; + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + let arch = "x86_64"; + let llvm_target = super::apple_base::macos_llvm_target(&arch); + Ok(Target { - llvm_target: "x86_64-apple-darwin".to_string(), + llvm_target: llvm_target, target_endian: "little".to_string(), target_pointer_width: "64".to_string(), target_c_int_width: "32".to_string(), data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(), - arch: "x86_64".to_string(), + arch: arch.to_string(), target_os: "macos".to_string(), target_env: String::new(), target_vendor: "apple".to_string(), diff --git a/src/test/codegen/i686-macosx-deployment-target.rs b/src/test/codegen/i686-macosx-deployment-target.rs new file mode 100644 index 00000000000..dad376d6677 --- /dev/null +++ b/src/test/codegen/i686-macosx-deployment-target.rs @@ -0,0 +1,26 @@ +// +// Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set. +// See issue #60235. + +// compile-flags: -O --target=i686-apple-darwin --crate-type=rlib +// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9 +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="freeze"] +trait Freeze { } +#[lang="copy"] +trait Copy { } + +#[repr(C)] +pub struct Bool { + b: bool, +} + +// CHECK: target triple = "i686-apple-macosx10.9.0" +#[no_mangle] +pub extern "C" fn structbool() -> Bool { + Bool { b: true } +} diff --git a/src/test/codegen/x86_64-macosx-deployment-target.rs b/src/test/codegen/x86_64-macosx-deployment-target.rs new file mode 100644 index 00000000000..8e291b7b298 --- /dev/null +++ b/src/test/codegen/x86_64-macosx-deployment-target.rs @@ -0,0 +1,26 @@ +// +// Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set. +// See issue #60235. + +// compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib +// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9 +#![feature(no_core, lang_items)] +#![no_core] + +#[lang="sized"] +trait Sized { } +#[lang="freeze"] +trait Freeze { } +#[lang="copy"] +trait Copy { } + +#[repr(C)] +pub struct Bool { + b: bool, +} + +// CHECK: target triple = "x86_64-apple-macosx10.9.0" +#[no_mangle] +pub extern "C" fn structbool() -> Bool { + Bool { b: true } +}