diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 816242129f338..2b64642b766ab 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -11,7 +11,7 @@ use std::ffi::CString; -use rustc::hir::CodegenFnAttrFlags; +use rustc::hir::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::session::Session; use rustc::session::config::Sanitizer; @@ -134,11 +134,37 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) { /// Composite function which sets LLVM attributes for function depending on its AST (#[attribute]) /// attributes. -pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) { - let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(id); +pub fn from_fn_attrs( + cx: &CodegenCx<'ll, '_>, + llfn: &'ll Value, + id: Option, +) { + let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id)) + .unwrap_or(CodegenFnAttrs::new()); inline(llfn, codegen_fn_attrs.inline); + // The `uwtable` attribute according to LLVM is: + // + // This attribute indicates that the ABI being targeted requires that an + // unwind table entry be produced for this function even if we can show + // that no exceptions passes by it. This is normally the case for the + // ELF x86-64 abi, but it can be disabled for some compilation units. + // + // Typically when we're compiling with `-C panic=abort` (which implies this + // `no_landing_pads` check) we don't need `uwtable` because we can't + // generate any exceptions! On Windows, however, exceptions include other + // events such as illegal instructions, segfaults, etc. This means that on + // Windows we end up still needing the `uwtable` attribute even if the `-C + // panic=abort` flag is passed. + // + // You can also find more info on why Windows is whitelisted here in: + // https://bugzilla.mozilla.org/show_bug.cgi?id=1302078 + if !cx.sess().no_landing_pads() || + cx.sess().target.target.options.requires_uwtable { + attributes::emit_uwtable(llfn, true); + } + set_frame_pointer_elimination(cx, llfn); set_probestack(cx, llfn); @@ -162,7 +188,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) { // *in Rust code* may unwind. Foreign items like `extern "C" { // fn foo(); }` are assumed not to unwind **unless** they have // a `#[unwind]` attribute. - } else if !cx.tcx.is_foreign_item(id) { + } else if id.map(|id| !cx.tcx.is_foreign_item(id)).unwrap_or(false) { Some(true) } else { None @@ -208,14 +234,16 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) { // Note that currently the `wasm-import-module` doesn't do anything, but // eventually LLVM 7 should read this and ferry the appropriate import // module to the output file. - if cx.tcx.sess.target.target.arch == "wasm32" { - if let Some(module) = wasm_import_module(cx.tcx, id) { - llvm::AddFunctionAttrStringValue( - llfn, - llvm::AttributePlace::Function, - const_cstr!("wasm-import-module"), - &module, - ); + if let Some(id) = id { + if cx.tcx.sess.target.target.arch == "wasm32" { + if let Some(module) = wasm_import_module(cx.tcx, id) { + llvm::AddFunctionAttrStringValue( + llfn, + llvm::AttributePlace::Function, + const_cstr!("wasm-import-module"), + &module, + ); + } } } } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index e626cc3870fe9..bd0c62e4766ae 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -503,27 +503,6 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<' cx.stats.borrow_mut().n_closures += 1; - // The `uwtable` attribute according to LLVM is: - // - // This attribute indicates that the ABI being targeted requires that an - // unwind table entry be produced for this function even if we can show - // that no exceptions passes by it. This is normally the case for the - // ELF x86-64 abi, but it can be disabled for some compilation units. - // - // Typically when we're compiling with `-C panic=abort` (which implies this - // `no_landing_pads` check) we don't need `uwtable` because we can't - // generate any exceptions! On Windows, however, exceptions include other - // events such as illegal instructions, segfaults, etc. This means that on - // Windows we end up still needing the `uwtable` attribute even if the `-C - // panic=abort` flag is passed. - // - // You can also find more info on why Windows is whitelisted here in: - // https://bugzilla.mozilla.org/show_bug.cgi?id=1302078 - if !cx.sess().no_landing_pads() || - cx.sess().target.target.options.requires_uwtable { - attributes::emit_uwtable(lldecl, true); - } - let mir = cx.tcx.instance_mir(instance.def); mir::codegen_mir(cx, lldecl, &mir, instance, sig); } diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 3594351802fe9..2e90f95fa8e2d 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -98,7 +98,7 @@ pub fn get_fn( if instance.def.is_inline(tcx) { attributes::inline(llfn, attributes::InlineAttr::Hint); } - attributes::from_fn_attrs(cx, llfn, instance.def.def_id()); + attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id())); let instance_def_id = instance.def_id(); diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 0b5a6757333f2..099d8562aa536 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -10,6 +10,7 @@ #![allow(non_upper_case_globals)] +use attributes; use intrinsics::{self, Intrinsic}; use llvm::{self, TypeKind}; use abi::{Abi, FnType, LlvmType, PassMode}; @@ -944,6 +945,7 @@ fn gen_fn<'ll, 'tcx>( Abi::Rust ))); let llfn = declare::define_internal_fn(cx, name, rust_fn_ty); + attributes::from_fn_attrs(cx, llfn, None); let bx = Builder::new_block(cx, llfn, "entry-block"); codegen(bx); llfn diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index 80c4df1d6b005..7f25911abec35 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -182,7 +182,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, if instance.def.is_inline(cx.tcx) { attributes::inline(lldecl, attributes::InlineAttr::Hint); } - attributes::from_fn_attrs(cx, lldecl, instance.def.def_id()); + attributes::from_fn_attrs(cx, lldecl, Some(instance.def.def_id())); cx.instances.borrow_mut().insert(instance, lldecl); }