]> git.lizzy.rs Git - rust.git/commitdiff
Set more llvm function attributes for __rust_try
authorAlex Crichton <alex@alexcrichton.com>
Thu, 16 Aug 2018 20:19:04 +0000 (13:19 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 16 Aug 2018 20:23:35 +0000 (13:23 -0700)
This shim is generated elsewhere in the compiler so this commit adds support to
ensure it goes through similar paths as the rest of the compiler to set llvm
function attributes like target features.

cc #53372

src/librustc_codegen_llvm/attributes.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/callee.rs
src/librustc_codegen_llvm/intrinsic.rs
src/librustc_codegen_llvm/mono_item.rs

index 816242129f338e080b5061bfc424cf2f5e1c84b2..2b64642b766ab9d8a5d85580e0844081d8b089c8 100644 (file)
@@ -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,
+                );
+            }
         }
     }
 }
index 7ca6a89dd9b57f1164bc6873def4468f023f147b..63573cc6fb06903299b6b547b13ec034131c9f9c 100644 (file)
@@ -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);
 }
index 3594351802fe91cabf67112f5c7b2f6ebae108ba..2e90f95fa8e2d88b7032f05b05ebe4b85eaa8f50 100644 (file)
@@ -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();
 
index 0b5a6757333f252c2c32b4b993c7bd5322b5c477..099d8562aa536ce025c4eef696e11fe99ff85a86 100644 (file)
@@ -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
index 80c4df1d6b0050e353cb454b39e45fdec000055f..7f25911abec35a11813c73bf9401104f1435bad3 100644 (file)
@@ -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);
 }