Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check target abi support #36421

Merged
merged 2 commits into from
Oct 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/librustc_back/target/aarch64_apple_ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub fn target() -> TargetResult {
features: "+neon,+fp-armv8,+cyclone".to_string(),
eliminate_frame_pointer: false,
max_atomic_width: Some(128),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_back/target/aarch64_linux_android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::{Target, TargetResult};
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::android_base::opts();
Expand All @@ -25,6 +25,9 @@ pub fn target() -> TargetResult {
target_os: "android".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
options: base,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
}
7 changes: 5 additions & 2 deletions src/librustc_back/target/aarch64_unknown_linux_gnu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::{Target, TargetResult};
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::linux_base::opts();
Expand All @@ -22,6 +22,9 @@ pub fn target() -> TargetResult {
arch: "aarch64".to_string(),
target_os: "linux".to_string(),
target_vendor: "unknown".to_string(),
options: base,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
}
16 changes: 16 additions & 0 deletions src/librustc_back/target/arm_base.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// 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.

use syntax::abi::Abi;

// All the calling conventions trigger an assertion(Unsupported calling convention) in llvm on arm
pub fn abi_blacklist() -> Vec<Abi> {
vec![Abi::Stdcall, Abi::Fastcall, Abi::Vectorcall, Abi::Win64, Abi::SysV64]
}
7 changes: 5 additions & 2 deletions src/librustc_back/target/arm_linux_androideabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::{Target, TargetResult};
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::android_base::opts();
Expand All @@ -24,6 +24,9 @@ pub fn target() -> TargetResult {
target_os: "android".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
options: base,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
}
1 change: 1 addition & 0 deletions src/librustc_back/target/arm_unknown_linux_gnueabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn target() -> TargetResult {

options: TargetOptions {
features: "+v6".to_string(),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/arm_unknown_linux_gnueabihf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn target() -> TargetResult {

options: TargetOptions {
features: "+v6,+vfp2".to_string(),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
}
})
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_back/target/arm_unknown_linux_musleabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::{Target, TargetResult};
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
Expand All @@ -29,6 +29,9 @@ pub fn target() -> TargetResult {
target_os: "linux".to_string(),
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
options: base,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
}
7 changes: 5 additions & 2 deletions src/librustc_back/target/arm_unknown_linux_musleabihf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::{Target, TargetResult};
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
Expand All @@ -29,6 +29,9 @@ pub fn target() -> TargetResult {
target_os: "linux".to_string(),
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
options: base,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
}
1 change: 1 addition & 0 deletions src/librustc_back/target/armv7_apple_ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn target() -> TargetResult {
options: TargetOptions {
features: "+v7,+vfp3,+neon".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
}
})
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_back/target/armv7_linux_androideabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::{Target, TargetResult};
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::android_base::opts();
Expand All @@ -24,6 +24,9 @@ pub fn target() -> TargetResult {
target_os: "android".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
options: base,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
}
1 change: 1 addition & 0 deletions src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub fn target() -> TargetResult {
features: "+v7,+vfp3,+d16,+thumb2,-neon".to_string(),
cpu: "generic".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
}
})
Expand Down
7 changes: 5 additions & 2 deletions src/librustc_back/target/armv7_unknown_linux_musleabihf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use target::{Target, TargetResult};
use target::{Target, TargetOptions, TargetResult};

pub fn target() -> TargetResult {
let mut base = super::linux_musl_base::opts();
Expand All @@ -30,6 +30,9 @@ pub fn target() -> TargetResult {
target_os: "linux".to_string(),
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
options: base,
options: TargetOptions {
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
},
})
}
1 change: 1 addition & 0 deletions src/librustc_back/target/armv7s_apple_ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn target() -> TargetResult {
options: TargetOptions {
features: "+v7,+vfp4,+neon".to_string(),
max_atomic_width: Some(64),
abi_blacklist: super::arm_base::abi_blacklist(),
.. base
}
})
Expand Down
34 changes: 33 additions & 1 deletion src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ use serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
use std::default::Default;
use std::io::prelude::*;
use syntax::abi::Abi;
use syntax::abi::{Abi, lookup as lookup_abi};

use PanicStrategy;

mod android_base;
mod apple_base;
mod apple_ios_base;
mod arm_base;
mod bitrig_base;
mod dragonfly_base;
mod freebsd_base;
Expand Down Expand Up @@ -358,6 +359,10 @@ pub struct TargetOptions {

/// Panic strategy: "unwind" or "abort"
pub panic_strategy: PanicStrategy,

/// A blacklist of ABIs unsupported by the current target. Note that generic
/// ABIs are considered to be supported on all platforms and cannot be blacklisted.
pub abi_blacklist: Vec<Abi>,
}

impl Default for TargetOptions {
Expand Down Expand Up @@ -408,6 +413,7 @@ impl Default for TargetOptions {
obj_is_bitcode: false,
max_atomic_width: None,
panic_strategy: PanicStrategy::Unwind,
abi_blacklist: vec![],
}
}
}
Expand All @@ -433,6 +439,10 @@ impl Target {
self.options.max_atomic_width.unwrap_or(self.target_pointer_width.parse().unwrap())
}

pub fn is_abi_supported(&self, abi: Abi) -> bool {
abi.generic() || !self.options.abi_blacklist.contains(&abi)
}

/// Load a target descriptor from a JSON object.
pub fn from_json(obj: Json) -> TargetResult {
// While ugly, this code must remain this way to retain
Expand Down Expand Up @@ -564,6 +574,22 @@ impl Target {
key!(max_atomic_width, Option<u64>);
try!(key!(panic_strategy, PanicStrategy));

if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
for name in array.iter().filter_map(|abi| abi.as_string()) {
match lookup_abi(name) {
Some(abi) => {
if abi.generic() {
return Err(format!("The ABI \"{}\" is considered to be supported on \
all targets and cannot be blacklisted", abi))
}

base.options.abi_blacklist.push(abi)
}
None => return Err(format!("Unknown ABI \"{}\" in target specification", name))
}
}
}

Ok(base)
}

Expand Down Expand Up @@ -707,6 +733,12 @@ impl ToJson for Target {
target_option_val!(max_atomic_width);
target_option_val!(panic_strategy);

if default.abi_blacklist != self.options.abi_blacklist {
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
.map(Abi::name).map(|name| name.to_json())
.collect::<Vec<_>>().to_json());
}

Json::Object(d)
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/thumb_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub fn opts() -> TargetOptions {
// Similarly, one almost always never wants to use relocatable code because of the extra
// costs it involves.
relocation_model: "static".to_string(),
abi_blacklist: super::arm_base::abi_blacklist(),
.. Default::default()
}
}
20 changes: 16 additions & 4 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,13 +531,16 @@ pub fn check_drop_impls(ccx: &CrateCtxt) -> CompileResult {
fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
decl: &'tcx hir::FnDecl,
body: &'tcx hir::Block,
fn_id: ast::NodeId) {
fn_id: ast::NodeId,
span: Span) {
let raw_fty = ccx.tcx.lookup_item_type(ccx.tcx.map.local_def_id(fn_id)).ty;
let fn_ty = match raw_fty.sty {
ty::TyFnDef(.., f) => f,
_ => span_bug!(body.span, "check_bare_fn: function type expected")
};

check_abi(ccx, span, fn_ty.abi);

ccx.inherited(fn_id).enter(|inh| {
// Compute the fty from point of view of inside fn.
let fn_scope = inh.tcx.region_maps.call_site_extent(fn_id, body.id);
Expand All @@ -561,6 +564,13 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
});
}

fn check_abi<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, abi: Abi) {
if !ccx.tcx.sess.target.target.is_abi_supported(abi) {
struct_span_err!(ccx.tcx.sess, span, E0570,
"The ABI `{}` is not supported for the current target", abi).emit()
}
}

struct GatherLocalsVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fcx: &'a FnCtxt<'a, 'gcx, 'tcx>
}
Expand Down Expand Up @@ -767,6 +777,8 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
check_bounds_are_used(ccx, generics, pty_ty);
}
hir::ItemForeignMod(ref m) => {
check_abi(ccx, it.span, m.abi);

if m.abi == Abi::RustIntrinsic {
for item in &m.items {
intrinsic::check_intrinsic_type(ccx, item);
Expand Down Expand Up @@ -804,7 +816,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
let _indenter = indenter();
match it.node {
hir::ItemFn(ref decl, .., ref body) => {
check_bare_fn(ccx, &decl, &body, it.id);
check_bare_fn(ccx, &decl, &body, it.id, it.span);
}
hir::ItemImpl(.., ref impl_items) => {
debug!("ItemImpl {} with id {}", it.name, it.id);
Expand All @@ -815,7 +827,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
check_const(ccx, &expr, impl_item.id)
}
hir::ImplItemKind::Method(ref sig, ref body) => {
check_bare_fn(ccx, &sig.decl, body, impl_item.id);
check_bare_fn(ccx, &sig.decl, body, impl_item.id, impl_item.span);
}
hir::ImplItemKind::Type(_) => {
// Nothing to do here.
Expand All @@ -830,7 +842,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx hir::Item) {
check_const(ccx, &expr, trait_item.id)
}
hir::MethodTraitItem(ref sig, Some(ref body)) => {
check_bare_fn(ccx, &sig.decl, body, trait_item.id);
check_bare_fn(ccx, &sig.decl, body, trait_item.id, trait_item.span);
}
hir::MethodTraitItem(_, None) |
hir::ConstTraitItem(_, None) |
Expand Down
10 changes: 10 additions & 0 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4156,6 +4156,16 @@ let s = Simba { mother: 1, father: 0 }; // ok!
```
"##,

E0570: r##"
The requested ABI is unsupported by the current target.

The rust compiler maintains for each target a blacklist of ABIs unsupported on
that target. If an ABI is present in such a list this usually means that the
target / ABI combination is currently unsupported by llvm.

If necessary, you can circumvent this check using custom target specifications.
"##,

}

register_diagnostics! {
Expand Down
Loading