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:
Huon Wilson 2015-01-16 10:16:20 +11:00
parent 4f08de84c9
commit c8e0e9549d
4 changed files with 64 additions and 2 deletions

View File

@ -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

View File

@ -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)
}

View 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() {}

View File

@ -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)]