Feature gate SIMD in FFI, due to unknown ABIs.
I don't know if this handling of SIMD types is correct for the C ABI on all platforms, so lets add an even finer feature gate than just the `simd` one. The `simd` one can be used with (relatively) little risk of complete nonsense, the reason for it is that it is likely that things will change. Using the types in FFI with an incorrect ABI will at best give absolute nonsense results, but possibly cause serious breakage too, so this is a step up in badness, hence a new feature gate.
This commit is contained in:
parent
4f08de84c9
commit
c8e0e9549d
@ -36,6 +36,7 @@ use syntax::parse::token::{InternedString, special_idents};
|
||||
use syntax::parse::token;
|
||||
use syntax::{ast};
|
||||
use syntax::{attr, ast_map};
|
||||
use syntax::print::pprust;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -426,16 +427,47 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
return bcx;
|
||||
}
|
||||
|
||||
// feature gate SIMD types in FFI, since I (huonw) am not sure the
|
||||
// ABIs are handled at all correctly.
|
||||
fn gate_simd_ffi(tcx: &ty::ctxt, decl: &ast::FnDecl, ty: &ty::BareFnTy) {
|
||||
if !tcx.sess.features.borrow().simd_ffi {
|
||||
let check = |&: ast_ty: &ast::Ty, ty: ty::Ty| {
|
||||
if ty::type_is_simd(tcx, ty) {
|
||||
tcx.sess.span_err(ast_ty.span,
|
||||
&format!("use of SIMD type `{}` in FFI is highly experimental and \
|
||||
may result in invalid code",
|
||||
pprust::ty_to_string(ast_ty))[]);
|
||||
tcx.sess.span_help(ast_ty.span,
|
||||
"add #![feature(simd_ffi)] to the crate attributes to enable");
|
||||
}
|
||||
};
|
||||
let sig = &ty.sig.0;
|
||||
for (input, ty) in decl.inputs.iter().zip(sig.inputs.iter()) {
|
||||
check(&*input.ty, *ty)
|
||||
}
|
||||
match decl.output {
|
||||
ast::NoReturn(_) => {}
|
||||
ast::Return(ref ty) => check(&**ty, sig.output.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
|
||||
let _icx = push_ctxt("foreign::trans_foreign_mod");
|
||||
for foreign_item in foreign_mod.items.iter() {
|
||||
let lname = link_name(&**foreign_item);
|
||||
|
||||
if let ast::ForeignItemFn(..) = foreign_item.node {
|
||||
if let ast::ForeignItemFn(ref decl, _) = foreign_item.node {
|
||||
match foreign_mod.abi {
|
||||
Rust | RustIntrinsic => {}
|
||||
abi => {
|
||||
let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);
|
||||
match ty.sty {
|
||||
ty::ty_bare_fn(_, bft) => gate_simd_ffi(ccx.tcx(), &**decl, bft),
|
||||
_ => ccx.tcx().sess.span_bug(foreign_item.span,
|
||||
"foreign fn's sty isn't a bare_fn_ty?")
|
||||
}
|
||||
|
||||
register_foreign_item_fn(ccx, abi, ty,
|
||||
&lname.get()[]);
|
||||
// Unlike for other items, we shouldn't call
|
||||
|
@ -72,6 +72,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
|
||||
("slicing_syntax", Active),
|
||||
("box_syntax", Active),
|
||||
("on_unimplemented", Active),
|
||||
("simd_ffi", Active),
|
||||
|
||||
("if_let", Accepted),
|
||||
("while_let", Accepted),
|
||||
@ -128,6 +129,7 @@ pub struct Features {
|
||||
pub visible_private_types: bool,
|
||||
pub quote: bool,
|
||||
pub old_orphan_check: bool,
|
||||
pub simd_ffi: bool,
|
||||
}
|
||||
|
||||
impl Features {
|
||||
@ -139,6 +141,7 @@ impl Features {
|
||||
visible_private_types: false,
|
||||
quote: false,
|
||||
old_orphan_check: false,
|
||||
simd_ffi: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -524,6 +527,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
|
||||
visible_private_types: cx.has_feature("visible_private_types"),
|
||||
quote: cx.has_feature("quote"),
|
||||
old_orphan_check: cx.has_feature("old_orphan_check"),
|
||||
simd_ffi: cx.has_feature("simd_ffi"),
|
||||
},
|
||||
unknown_features)
|
||||
}
|
||||
|
26
src/test/compile-fail/feature-gate-simd-ffi.rs
Normal file
26
src/test/compile-fail/feature-gate-simd-ffi.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright 2015 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(simd)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::simd::f32x4;
|
||||
|
||||
#[simd] #[derive(Copy)] #[repr(C)] struct LocalSimd(u8, u8);
|
||||
|
||||
extern {
|
||||
fn foo() -> f32x4; //~ ERROR use of SIMD type
|
||||
fn bar(x: f32x4); //~ ERROR use of SIMD type
|
||||
|
||||
fn baz() -> LocalSimd; //~ ERROR use of SIMD type
|
||||
fn qux(x: LocalSimd); //~ ERROR use of SIMD type
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -14,7 +14,7 @@
|
||||
// cross-compiled standard libraries.
|
||||
#![no_std]
|
||||
|
||||
#![feature(simd, link_llvm_intrinsics, lang_items)]
|
||||
#![feature(simd, simd_ffi, link_llvm_intrinsics, lang_items)]
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user