about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_codegen_llvm/attributes.rs52
-rw-r--r--src/librustc_codegen_llvm/base.rs21
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs2
-rw-r--r--src/librustc_codegen_llvm/mono_item.rs2
5 files changed, 44 insertions, 35 deletions
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index 816242129f3..2b64642b766 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<DefId>,
+) {
+    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 e626cc3870f..bd0c62e4766 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 3594351802f..2e90f95fa8e 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 0b5a6757333..099d8562aa5 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 80c4df1d6b0..7f25911abec 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);
 }