diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 3f6d34617c832..79d0aed10ed78 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -81,10 +81,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> { self.tcx.sess.span_err(attr.span, "\ must only be attached to foreign modules"); } - } else if attr.check_name("wasm_custom_section") { - if target != Target::Const { - self.tcx.sess.span_err(attr.span, "only allowed on consts"); - } } } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index c1a885d80bf8b..1df756d204de7 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2266,20 +2266,22 @@ pub struct CodegenFnAttrs { pub export_name: Option, pub target_features: Vec, pub linkage: Option, - pub wasm_custom_section: Option, + pub link_section: Option, } bitflags! { #[derive(RustcEncodable, RustcDecodable)] - pub struct CodegenFnAttrFlags: u8 { - const COLD = 0b0000_0001; - const ALLOCATOR = 0b0000_0010; - const UNWIND = 0b0000_0100; - const RUSTC_ALLOCATOR_NOUNWIND = 0b0000_1000; - const NAKED = 0b0001_0000; - const NO_MANGLE = 0b0010_0000; - const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000; - const NO_DEBUG = 0b1000_0000; + pub struct CodegenFnAttrFlags: u32 { + const COLD = 1 << 0; + const ALLOCATOR = 1 << 1; + const UNWIND = 1 << 2; + const RUSTC_ALLOCATOR_NOUNWIND = 1 << 3; + const NAKED = 1 << 4; + const NO_MANGLE = 1 << 5; + const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6; + const NO_DEBUG = 1 << 7; + const THREAD_LOCAL = 1 << 8; + const USED = 1 << 9; } } @@ -2291,7 +2293,7 @@ impl CodegenFnAttrs { export_name: None, target_features: vec![], linkage: None, - wasm_custom_section: None, + link_section: None, } } diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index d1fb05ceafbfd..28f3f20a82bc5 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -1120,7 +1120,7 @@ impl_stable_hash_for!(struct hir::CodegenFnAttrs { export_name, target_features, linkage, - wasm_custom_section, + link_section, }); impl<'hir> HashStable> for hir::CodegenFnAttrFlags diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index da59bced760d4..126abb0d359bb 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -313,11 +313,6 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt, return true; } - // These constants are special for wasm - if attr::contains_name(attrs, "wasm_custom_section") { - return true; - } - tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow } diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 79566fbbc11a4..f0d6b8170eb64 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -24,7 +24,6 @@ pub enum MonoItem<'tcx> { Fn(Instance<'tcx>), Static(DefId), GlobalAsm(NodeId), - CustomSection(DefId), } impl<'tcx> MonoItem<'tcx> { @@ -38,8 +37,7 @@ impl<'tcx> MonoItem<'tcx> { // Conservatively estimate the size of a static declaration // or assembly to be 1. MonoItem::Static(_) | - MonoItem::GlobalAsm(_) | - MonoItem::CustomSection(_) => 1, + MonoItem::GlobalAsm(_) => 1, } } } @@ -54,8 +52,7 @@ impl<'a, 'tcx> HashStable> for MonoItem<'tcx> { MonoItem::Fn(ref instance) => { instance.hash_stable(hcx, hasher); } - MonoItem::Static(def_id) | - MonoItem::CustomSection(def_id) => { + MonoItem::Static(def_id) => { def_id.hash_stable(hcx, hasher); } MonoItem::GlobalAsm(node_id) => { diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index d4d0b67523e11..6d37f1ca3cafc 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -33,7 +33,6 @@ use back::link; use back::write::{self, OngoingCodegen, create_target_machine}; use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param}; use llvm; -use libc::c_uint; use metadata; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::middle::lang_items::StartFnLangItem; @@ -87,8 +86,7 @@ use std::sync::mpsc; use syntax_pos::Span; use syntax_pos::symbol::InternedString; use syntax::attr; -use rustc::hir; -use syntax::ast; +use rustc::hir::{self, CodegenFnAttrs}; use mir::operand::OperandValue; @@ -513,17 +511,14 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<' mir::codegen_mir(cx, lldecl, &mir, instance, sig); } -pub fn set_link_section(cx: &CodegenCx, - llval: ValueRef, - attrs: &[ast::Attribute]) { - if let Some(sect) = attr::first_attr_value_str_by_name(attrs, "link_section") { - if contains_null(§.as_str()) { - cx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", §)); - } - unsafe { - let buf = CString::new(sect.as_str().as_bytes()).unwrap(); - llvm::LLVMSetSection(llval, buf.as_ptr()); - } +pub fn set_link_section(llval: ValueRef, attrs: &CodegenFnAttrs) { + let sect = match attrs.link_section { + Some(name) => name, + None => return, + }; + unsafe { + let buf = CString::new(sect.as_str().as_bytes()).unwrap(); + llvm::LLVMSetSection(llval, buf.as_ptr()); } } @@ -613,10 +608,6 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) { } } -fn contains_null(s: &str) -> bool { - s.bytes().any(|b| b == 0) -} - fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, llmod_id: &str, link_meta: &LinkMeta) @@ -1369,42 +1360,3 @@ mod temp_stable_hash_impls { } } } - -pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) { - use rustc::mir::interpret::GlobalId; - - assert!(cx.tcx.sess.opts.target_triple.triple().starts_with("wasm32")); - - info!("loading wasm section {:?}", def_id); - - let section = cx.tcx.codegen_fn_attrs(def_id).wasm_custom_section.unwrap(); - - let instance = ty::Instance::mono(cx.tcx, def_id); - let cid = GlobalId { - instance, - promoted: None - }; - let param_env = ty::ParamEnv::reveal_all(); - let val = cx.tcx.const_eval(param_env.and(cid)).unwrap(); - let alloc = cx.tcx.const_value_to_allocation(val); - - unsafe { - let section = llvm::LLVMMDStringInContext( - cx.llcx, - section.as_str().as_ptr() as *const _, - section.as_str().len() as c_uint, - ); - let alloc = llvm::LLVMMDStringInContext( - cx.llcx, - alloc.bytes.as_ptr() as *const _, - alloc.bytes.len() as c_uint, - ); - let data = [section, alloc]; - let meta = llvm::LLVMMDNodeInContext(cx.llcx, data.as_ptr(), 2); - llvm::LLVMAddNamedMetadataOperand( - cx.llmod, - "wasm.custom_sections\0".as_ptr() as *const _, - meta, - ); - } -} diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs index 6e3096d4cd5ba..5c00947889dfe 100644 --- a/src/librustc_codegen_llvm/consts.rs +++ b/src/librustc_codegen_llvm/consts.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use libc::c_uint; use llvm; use llvm::{SetUnnamedAddr}; use llvm::{ValueRef, True}; @@ -24,11 +25,9 @@ use type_of::LayoutLlvmExt; use rustc::ty; use rustc::ty::layout::{Align, LayoutOf}; -use rustc::hir; +use rustc::hir::{self, CodegenFnAttrFlags}; use std::ffi::{CStr, CString}; -use syntax::ast; -use syntax::attr; pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef { unsafe { @@ -244,11 +243,10 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef { } pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, - def_id: DefId, - is_mutable: bool, - attrs: &[ast::Attribute]) { + def_id: DefId, + is_mutable: bool) { unsafe { - let g = get_static(cx, def_id); + let attrs = cx.tcx.codegen_fn_attrs(def_id); let (v, alloc) = match ::mir::codegen_static_initializer(cx, def_id) { Ok(v) => v, @@ -256,6 +254,8 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, Err(_) => return, }; + let g = get_static(cx, def_id); + // boolean SSA values are i1, but they have to be stored in i8 slots, // otherwise some LLVM optimization passes don't work as expected let mut val_llty = val_ty(v); @@ -307,7 +307,7 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, debuginfo::create_global_var_metadata(cx, def_id, g); - if attr::contains_name(attrs, "thread_local") { + if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { llvm::set_thread_local_mode(g, cx.tls_model); // Do not allow LLVM to change the alignment of a TLS on macOS. @@ -349,9 +349,34 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, } } - base::set_link_section(cx, g, attrs); - if attr::contains_name(attrs, "used") { + // Wasm statics with custom link sections get special treatment as they + // go into custom sections of the wasm executable. + if cx.tcx.sess.opts.target_triple.triple().starts_with("wasm32") { + if let Some(section) = attrs.link_section { + let section = llvm::LLVMMDStringInContext( + cx.llcx, + section.as_str().as_ptr() as *const _, + section.as_str().len() as c_uint, + ); + let alloc = llvm::LLVMMDStringInContext( + cx.llcx, + alloc.bytes.as_ptr() as *const _, + alloc.bytes.len() as c_uint, + ); + let data = [section, alloc]; + let meta = llvm::LLVMMDNodeInContext(cx.llcx, data.as_ptr(), 2); + llvm::LLVMAddNamedMetadataOperand( + cx.llmod, + "wasm.custom_sections\0".as_ptr() as *const _, + meta, + ); + } + } else { + base::set_link_section(g, &attrs); + } + + if attrs.flags.contains(CodegenFnAttrFlags::USED) { // This static will be stored in the llvm.used variable which is an array of i8* let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref()); cx.used_statics.borrow_mut().push(cast); diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index b512a6f1bb4b0..a528008e3b4bd 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -54,9 +54,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { bug!("Expected Def::Static for {:?}, found nothing", def_id) } }; - let attrs = tcx.get_attrs(def_id); - - consts::codegen_static(&cx, def_id, is_mutable, &attrs); + consts::codegen_static(&cx, def_id, is_mutable); } MonoItem::GlobalAsm(node_id) => { let item = cx.tcx.hir.expect_item(node_id); @@ -66,9 +64,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type") } } - MonoItem::CustomSection(def_id) => { - base::define_custom_section(cx, def_id); - } MonoItem::Fn(instance) => { base::codegen_instance(&cx, instance); } @@ -100,7 +95,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { MonoItem::Fn(instance) => { predefine_fn(cx, instance, linkage, visibility, &symbol_name); } - MonoItem::CustomSection(..) => {} MonoItem::GlobalAsm(..) => {} } @@ -120,9 +114,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> { MonoItem::Static(id) => { format!("Static({:?})", id) } - MonoItem::CustomSection(id) => { - format!("CustomSection({:?})", id) - } MonoItem::GlobalAsm(id) => { format!("GlobalAsm({:?})", id) } @@ -164,10 +155,10 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, !instance.substs.has_param_types()); let mono_ty = instance.ty(cx.tcx); - let attrs = instance.def.attrs(cx.tcx); + let attrs = cx.tcx.codegen_fn_attrs(instance.def_id()); let lldecl = declare::declare_fn(cx, symbol_name, mono_ty); unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) }; - base::set_link_section(cx, lldecl, &attrs); + base::set_link_section(lldecl, &attrs); if linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR { llvm::SetUniqueComdat(cx.llmod, lldecl); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index a2d620db9243f..2f983e25acd74 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -414,9 +414,6 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, MonoItem::GlobalAsm(..) => { recursion_depth_reset = None; } - MonoItem::CustomSection(..) => { - recursion_depth_reset = None; - } } record_accesses(tcx, starting_point, &neighbors[..], inlining_map); @@ -993,13 +990,6 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemKind::Const(..) => { // const items only generate mono items if they are // actually used somewhere. Just declaring them is insufficient. - - let def_id = self.tcx.hir.local_def_id(item.id); - if self.tcx.sess.opts.target_triple.triple().starts_with("wasm32") && - self.tcx.codegen_fn_attrs(def_id).wasm_custom_section.is_some() - { - self.output.push(MonoItem::CustomSection(def_id)); - } } hir::ItemKind::Fn(..) => { let def_id = self.tcx.hir.local_def_id(item.id); diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 1389ad63c3a3b..95968c0ea4f1f 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -63,7 +63,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { instance.substs.types().next().is_some() } MonoItem::Static(..) | - MonoItem::CustomSection(..) | MonoItem::GlobalAsm(..) => false, } } @@ -74,9 +73,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { MonoItem::Static(def_id) => { tcx.symbol_name(Instance::mono(tcx, def_id)) } - MonoItem::CustomSection(def_id) => { - tcx.symbol_name(Instance::mono(tcx, def_id)) - } MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); ty::SymbolName { @@ -126,7 +122,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { } } MonoItem::Static(..) | - MonoItem::CustomSection(..) | MonoItem::GlobalAsm(..) => { InstantiationMode::GloballyShared { may_conflict: false } } @@ -137,7 +132,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { let def_id = match *self.as_mono_item() { MonoItem::Fn(ref instance) => instance.def_id(), MonoItem::Static(def_id) => def_id, - MonoItem::CustomSection(..) => return None, MonoItem::GlobalAsm(..) => return None, }; @@ -175,7 +169,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { let (def_id, substs) = match *self.as_mono_item() { MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs), MonoItem::Static(def_id) => (def_id, Substs::empty()), - MonoItem::CustomSection(..) => return true, // global asm never has predicates MonoItem::GlobalAsm(..) => return true }; @@ -192,10 +185,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { let instance = Instance::new(def_id, tcx.intern_substs(&[])); to_string_internal(tcx, "static ", instance) }, - MonoItem::CustomSection(def_id) => { - let instance = Instance::new(def_id, tcx.intern_substs(&[])); - to_string_internal(tcx, "custom-section ", instance) - }, MonoItem::GlobalAsm(..) => { "global_asm".to_string() } @@ -221,9 +210,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug { MonoItem::Static(def_id) => { tcx.hir.as_local_node_id(def_id) } - MonoItem::CustomSection(def_id) => { - tcx.hir.as_local_node_id(def_id) - } MonoItem::GlobalAsm(node_id) => { Some(node_id) } diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 5f15870d6fbc3..f83ea6fa13b52 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -180,8 +180,7 @@ pub trait CodegenUnitExt<'tcx> { } } } - MonoItem::Static(def_id) | - MonoItem::CustomSection(def_id) => { + MonoItem::Static(def_id) => { tcx.hir.as_local_node_id(def_id) } MonoItem::GlobalAsm(node_id) => { @@ -450,9 +449,6 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; (Linkage::External, visibility) } - MonoItem::CustomSection(..) => { - (Linkage::External, Visibility::Hidden) - } MonoItem::GlobalAsm(node_id) => { let def_id = tcx.hir.local_def_id(node_id); let visibility = if tcx.is_reachable_non_generic(def_id) { @@ -718,7 +714,6 @@ fn characteristic_def_id_of_mono_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, Some(def_id) } MonoItem::Static(def_id) => Some(def_id), - MonoItem::CustomSection(def_id) => Some(def_id), MonoItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)), } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9f83f8a00b1f5..53d1e6008b8d9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1270,14 +1270,12 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item match it.node { // Consts can play a role in type-checking, so they are included here. hir::ItemKind::Static(..) => { - tcx.typeck_tables_of(tcx.hir.local_def_id(it.id)); + let def_id = tcx.hir.local_def_id(it.id); + tcx.typeck_tables_of(def_id); + maybe_check_static_with_link_section(tcx, def_id, it.span); } hir::ItemKind::Const(..) => { tcx.typeck_tables_of(tcx.hir.local_def_id(it.id)); - if it.attrs.iter().any(|a| a.check_name("wasm_custom_section")) { - let def_id = tcx.hir.local_def_id(it.id); - check_const_is_u8_array(tcx, def_id, it.span); - } } hir::ItemKind::Enum(ref enum_definition, _) => { check_enum(tcx, @@ -1350,19 +1348,38 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item } } -fn check_const_is_u8_array<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId, - span: Span) { - match tcx.type_of(def_id).sty { - ty::TyArray(t, _) => { - match t.sty { - ty::TyUint(ast::UintTy::U8) => return, - _ => {} - } +fn maybe_check_static_with_link_section(tcx: TyCtxt, id: DefId, span: Span) { + // Only restricted on wasm32 target for now + if !tcx.sess.opts.target_triple.triple().starts_with("wasm32") { + return + } + + // If `#[link_section]` is missing, then nothing to verify + let attrs = tcx.codegen_fn_attrs(id); + if attrs.link_section.is_none() { + return + } + + // For the wasm32 target statics with #[link_section] are placed into custom + // sections of the final output file, but this isn't link custom sections of + // other executable formats. Namely we can only embed a list of bytes, + // nothing with pointers to anything else or relocations. If any relocation + // show up, reject them here. + let instance = ty::Instance::mono(tcx, id); + let cid = GlobalId { + instance, + promoted: None + }; + let param_env = ty::ParamEnv::reveal_all(); + if let Ok(static_) = tcx.const_eval(param_env.and(cid)) { + let alloc = tcx.const_value_to_allocation(static_); + if alloc.relocations.len() != 0 { + let msg = "statics with a custom `#[link_section]` must be a \ + simple list of bytes on the wasm target with no \ + extra levels of indirection such as references"; + tcx.sess.span_err(span, msg); } - _ => {} } - tcx.sess.span_err(span, "must be an array of bytes like `[u8; N]`"); } fn check_on_unimplemented<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 4b628d6ffad75..03fa7f521d9ad 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1867,6 +1867,10 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; } else if attr.check_name("no_debug") { codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_DEBUG; + } else if attr.check_name("used") { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; + } else if attr.check_name("thread_local") { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; } else if attr.check_name("inline") { codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| { if attr.path != "inline" { @@ -1929,12 +1933,14 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen if let Some(val) = attr.value_str() { codegen_fn_attrs.linkage = Some(linkage_by_name(tcx, id, &val.as_str())); } - } else if attr.check_name("wasm_custom_section") { - match attr.value_str() { - Some(name) => codegen_fn_attrs.wasm_custom_section = Some(name), - None => { - tcx.sess.span_err(attr.span, "must be of the form \ - #[wasm_custom_section = \"foo\"]"); + } else if attr.check_name("link_section") { + if let Some(val) = attr.value_str() { + if val.as_str().bytes().any(|b| b == 0) { + let msg = format!("illegal null byte in link_section \ + value: `{}`", &val); + tcx.sess.span_err(attr.span, &msg); + } else { + codegen_fn_attrs.link_section = Some(val); } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f033c5006c53a..189a36427dbe6 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -417,9 +417,6 @@ declare_features! ( // `use path as _;` and `extern crate c as _;` (active, underscore_imports, "1.26.0", Some(48216), None), - // The #[wasm_custom_section] attribute - (active, wasm_custom_section, "1.26.0", Some(51088), None), - // The #![wasm_import_module] attribute (active, wasm_import_module, "1.26.0", Some(52090), None), @@ -1077,11 +1074,6 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "infer outlives requirements is an experimental feature", cfg_fn!(infer_outlives_requirements))), - ("wasm_custom_section", Whitelisted, Gated(Stability::Unstable, - "wasm_custom_section", - "attribute is currently unstable", - cfg_fn!(wasm_custom_section))), - // RFC 2070 ("panic_implementation", Normal, Gated(Stability::Unstable, "panic_implementation", diff --git a/src/test/incremental/issue-49595/issue_49595.rs b/src/test/incremental/issue-49595/issue_49595.rs index dfa92d425f436..134f114e6acca 100644 --- a/src/test/incremental/issue-49595/issue_49595.rs +++ b/src/test/incremental/issue-49595/issue_49595.rs @@ -15,7 +15,7 @@ #![feature(rustc_attrs)] #![crate_type = "rlib"] -#![rustc_partition_codegened(module="issue_49595-tests", cfg="cfail2")] +#![rustc_partition_codegened(module="issue_49595-__test", cfg="cfail2")] #![rustc_partition_codegened(module="issue_49595-lit_test", cfg="cfail3")] mod tests { diff --git a/src/test/run-make/wasm-custom-section/bar.rs b/src/test/run-make/wasm-custom-section/bar.rs index e3db36d6dbd4c..ed537280e6c52 100644 --- a/src/test/run-make/wasm-custom-section/bar.rs +++ b/src/test/run-make/wasm-custom-section/bar.rs @@ -14,11 +14,11 @@ extern crate foo; -#[wasm_custom_section = "foo"] -const A: [u8; 2] = [5, 6]; +#[link_section = "foo"] +pub static A: [u8; 2] = [5, 6]; -#[wasm_custom_section = "baz"] -const B: [u8; 2] = [7, 8]; +#[link_section = "baz"] +pub static B: [u8; 2] = [7, 8]; #[no_mangle] pub extern fn foo() {} diff --git a/src/test/run-make/wasm-custom-section/foo.rs b/src/test/run-make/wasm-custom-section/foo.rs index 44d1efd7c2d62..fb3bec31ada7f 100644 --- a/src/test/run-make/wasm-custom-section/foo.rs +++ b/src/test/run-make/wasm-custom-section/foo.rs @@ -12,8 +12,8 @@ #![feature(wasm_custom_section)] #![deny(warnings)] -#[wasm_custom_section = "foo"] -const A: [u8; 2] = [1, 2]; +#[link_section = "foo"] +pub static A: [u8; 2] = [1, 2]; -#[wasm_custom_section = "bar"] -const B: [u8; 2] = [3, 4]; +#[link_section = "bar"] +pub static B: [u8; 2] = [3, 4]; diff --git a/src/test/ui/feature-gate-wasm_custom_section.rs b/src/test/ui/feature-gate-wasm_custom_section.rs deleted file mode 100644 index c695ef4ff068f..0000000000000 --- a/src/test/ui/feature-gate-wasm_custom_section.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable -const A: [u8; 2] = [1, 2]; - -fn main() {} diff --git a/src/test/ui/feature-gate-wasm_custom_section.stderr b/src/test/ui/feature-gate-wasm_custom_section.stderr deleted file mode 100644 index 91f75d6817f95..0000000000000 --- a/src/test/ui/feature-gate-wasm_custom_section.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0658]: attribute is currently unstable (see issue #51088) - --> $DIR/feature-gate-wasm_custom_section.rs:11:1 - | -LL | #[wasm_custom_section = "foo"] //~ ERROR: attribute is currently unstable - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(wasm_custom_section)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/wasm-custom-section/malformed.rs b/src/test/ui/wasm-custom-section-relocations.rs similarity index 59% rename from src/test/ui/wasm-custom-section/malformed.rs rename to src/test/ui/wasm-custom-section-relocations.rs index 13b1685a48072..5631a70192afd 100644 --- a/src/test/ui/wasm-custom-section/malformed.rs +++ b/src/test/ui/wasm-custom-section-relocations.rs @@ -8,12 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(wasm_custom_section)] +// only-wasm32 -#[wasm_custom_section] //~ ERROR: must be of the form -const A: [u8; 1] = [0]; +#[link_section = "test"] +pub static A: &[u8] = &[1]; //~ ERROR: no extra levels of indirection -#[wasm_custom_section(foo)] //~ ERROR: must be of the form -const B: [u8; 1] = [0]; +#[link_section = "test"] +pub static B: [u8; 3] = [1, 2, 3]; -fn main() {} +#[link_section = "test"] +pub static C: usize = 3; + +#[link_section = "test"] +pub static D: &usize = &C; //~ ERROR: no extra levels of indirection diff --git a/src/test/ui/wasm-custom-section-relocations.stderr b/src/test/ui/wasm-custom-section-relocations.stderr new file mode 100644 index 0000000000000..9b96b99e02ae4 --- /dev/null +++ b/src/test/ui/wasm-custom-section-relocations.stderr @@ -0,0 +1,19 @@ +error[E0601]: `main` function not found in crate `wasm_custom_section_relocations` + | + = note: consider adding a `main` function to `$DIR/wasm-custom-section-relocations.rs` + +error: statics with a custom `#[link_section]` must be a simple list of bytes on the wasm target with no extra levels of indirection such as references + --> $DIR/wasm-custom-section-relocations.rs:14:1 + | +LL | pub static A: &[u8] = &[1]; //~ ERROR: no extra levels of indirection + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: statics with a custom `#[link_section]` must be a simple list of bytes on the wasm target with no extra levels of indirection such as references + --> $DIR/wasm-custom-section-relocations.rs:23:1 + | +LL | pub static D: &usize = &C; //~ ERROR: no extra levels of indirection + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/wasm-custom-section/malformed.stderr b/src/test/ui/wasm-custom-section/malformed.stderr deleted file mode 100644 index c716c824aebda..0000000000000 --- a/src/test/ui/wasm-custom-section/malformed.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: must be of the form #[wasm_custom_section = "foo"] - --> $DIR/malformed.rs:13:1 - | -LL | #[wasm_custom_section] //~ ERROR: must be of the form - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: must be of the form #[wasm_custom_section = "foo"] - --> $DIR/malformed.rs:16:1 - | -LL | #[wasm_custom_section(foo)] //~ ERROR: must be of the form - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/src/test/ui/wasm-custom-section/not-const.rs b/src/test/ui/wasm-custom-section/not-const.rs deleted file mode 100644 index 68077fb2fe4ac..0000000000000 --- a/src/test/ui/wasm-custom-section/not-const.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(wasm_custom_section)] - -#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts -static A: [u8; 2] = [1, 2]; - -#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts -struct B {} - -#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts -enum C {} - -#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts -impl B {} - -#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts -mod d {} - -#[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts -fn main() {} diff --git a/src/test/ui/wasm-custom-section/not-const.stderr b/src/test/ui/wasm-custom-section/not-const.stderr deleted file mode 100644 index 17c85b3e848eb..0000000000000 --- a/src/test/ui/wasm-custom-section/not-const.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error: only allowed on consts - --> $DIR/not-const.rs:13:1 - | -LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: only allowed on consts - --> $DIR/not-const.rs:16:1 - | -LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: only allowed on consts - --> $DIR/not-const.rs:19:1 - | -LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: only allowed on consts - --> $DIR/not-const.rs:22:1 - | -LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: only allowed on consts - --> $DIR/not-const.rs:25:1 - | -LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: only allowed on consts - --> $DIR/not-const.rs:28:1 - | -LL | #[wasm_custom_section = "foo"] //~ ERROR: only allowed on consts - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 6 previous errors - diff --git a/src/test/ui/wasm-custom-section/not-slice.rs b/src/test/ui/wasm-custom-section/not-slice.rs deleted file mode 100644 index 2d91641a5f756..0000000000000 --- a/src/test/ui/wasm-custom-section/not-slice.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(wasm_custom_section)] - -#[wasm_custom_section = "foo"] -const A: u8 = 0; //~ ERROR: must be an array of bytes - -#[wasm_custom_section = "foo"] -const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes - -#[wasm_custom_section = "foo"] -const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes - -fn main() {} diff --git a/src/test/ui/wasm-custom-section/not-slice.stderr b/src/test/ui/wasm-custom-section/not-slice.stderr deleted file mode 100644 index f2563ce0dddc1..0000000000000 --- a/src/test/ui/wasm-custom-section/not-slice.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: must be an array of bytes like `[u8; N]` - --> $DIR/not-slice.rs:14:1 - | -LL | const A: u8 = 0; //~ ERROR: must be an array of bytes - | ^^^^^^^^^^^^^^^^ - -error: must be an array of bytes like `[u8; N]` - --> $DIR/not-slice.rs:17:1 - | -LL | const B: &[u8] = &[0]; //~ ERROR: must be an array of bytes - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: must be an array of bytes like `[u8; N]` - --> $DIR/not-slice.rs:20:1 - | -LL | const C: &[u8; 1] = &[0]; //~ ERROR: must be an array of bytes - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors -