Skip to content

Commit 3188442

Browse files
committed
Set more llvm function attributes for __rust_try
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
1 parent d767ee1 commit 3188442

File tree

5 files changed

+44
-35
lines changed

5 files changed

+44
-35
lines changed

src/librustc_codegen_llvm/attributes.rs

+40-12
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
1212
use std::ffi::CString;
1313

14-
use rustc::hir::CodegenFnAttrFlags;
14+
use rustc::hir::{CodegenFnAttrFlags, CodegenFnAttrs};
1515
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
1616
use rustc::session::Session;
1717
use rustc::session::config::Sanitizer;
@@ -134,11 +134,37 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
134134

135135
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
136136
/// attributes.
137-
pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
138-
let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(id);
137+
pub fn from_fn_attrs(
138+
cx: &CodegenCx<'ll, '_>,
139+
llfn: &'ll Value,
140+
id: Option<DefId>,
141+
) {
142+
let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id))
143+
.unwrap_or(CodegenFnAttrs::new());
139144

140145
inline(llfn, codegen_fn_attrs.inline);
141146

147+
// The `uwtable` attribute according to LLVM is:
148+
//
149+
// This attribute indicates that the ABI being targeted requires that an
150+
// unwind table entry be produced for this function even if we can show
151+
// that no exceptions passes by it. This is normally the case for the
152+
// ELF x86-64 abi, but it can be disabled for some compilation units.
153+
//
154+
// Typically when we're compiling with `-C panic=abort` (which implies this
155+
// `no_landing_pads` check) we don't need `uwtable` because we can't
156+
// generate any exceptions! On Windows, however, exceptions include other
157+
// events such as illegal instructions, segfaults, etc. This means that on
158+
// Windows we end up still needing the `uwtable` attribute even if the `-C
159+
// panic=abort` flag is passed.
160+
//
161+
// You can also find more info on why Windows is whitelisted here in:
162+
// https://bugzilla.mozilla.org/show_bug.cgi?id=1302078
163+
if !cx.sess().no_landing_pads() ||
164+
cx.sess().target.target.options.requires_uwtable {
165+
attributes::emit_uwtable(llfn, true);
166+
}
167+
142168
set_frame_pointer_elimination(cx, llfn);
143169
set_probestack(cx, llfn);
144170

@@ -162,7 +188,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
162188
// *in Rust code* may unwind. Foreign items like `extern "C" {
163189
// fn foo(); }` are assumed not to unwind **unless** they have
164190
// a `#[unwind]` attribute.
165-
} else if !cx.tcx.is_foreign_item(id) {
191+
} else if id.map(|id| !cx.tcx.is_foreign_item(id)).unwrap_or(false) {
166192
Some(true)
167193
} else {
168194
None
@@ -208,14 +234,16 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
208234
// Note that currently the `wasm-import-module` doesn't do anything, but
209235
// eventually LLVM 7 should read this and ferry the appropriate import
210236
// module to the output file.
211-
if cx.tcx.sess.target.target.arch == "wasm32" {
212-
if let Some(module) = wasm_import_module(cx.tcx, id) {
213-
llvm::AddFunctionAttrStringValue(
214-
llfn,
215-
llvm::AttributePlace::Function,
216-
const_cstr!("wasm-import-module"),
217-
&module,
218-
);
237+
if let Some(id) = id {
238+
if cx.tcx.sess.target.target.arch == "wasm32" {
239+
if let Some(module) = wasm_import_module(cx.tcx, id) {
240+
llvm::AddFunctionAttrStringValue(
241+
llfn,
242+
llvm::AttributePlace::Function,
243+
const_cstr!("wasm-import-module"),
244+
&module,
245+
);
246+
}
219247
}
220248
}
221249
}

src/librustc_codegen_llvm/base.rs

-21
Original file line numberDiff line numberDiff line change
@@ -503,27 +503,6 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'
503503

504504
cx.stats.borrow_mut().n_closures += 1;
505505

506-
// The `uwtable` attribute according to LLVM is:
507-
//
508-
// This attribute indicates that the ABI being targeted requires that an
509-
// unwind table entry be produced for this function even if we can show
510-
// that no exceptions passes by it. This is normally the case for the
511-
// ELF x86-64 abi, but it can be disabled for some compilation units.
512-
//
513-
// Typically when we're compiling with `-C panic=abort` (which implies this
514-
// `no_landing_pads` check) we don't need `uwtable` because we can't
515-
// generate any exceptions! On Windows, however, exceptions include other
516-
// events such as illegal instructions, segfaults, etc. This means that on
517-
// Windows we end up still needing the `uwtable` attribute even if the `-C
518-
// panic=abort` flag is passed.
519-
//
520-
// You can also find more info on why Windows is whitelisted here in:
521-
// https://bugzilla.mozilla.org/show_bug.cgi?id=1302078
522-
if !cx.sess().no_landing_pads() ||
523-
cx.sess().target.target.options.requires_uwtable {
524-
attributes::emit_uwtable(lldecl, true);
525-
}
526-
527506
let mir = cx.tcx.instance_mir(instance.def);
528507
mir::codegen_mir(cx, lldecl, &mir, instance, sig);
529508
}

src/librustc_codegen_llvm/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub fn get_fn(
9898
if instance.def.is_inline(tcx) {
9999
attributes::inline(llfn, attributes::InlineAttr::Hint);
100100
}
101-
attributes::from_fn_attrs(cx, llfn, instance.def.def_id());
101+
attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id()));
102102

103103
let instance_def_id = instance.def_id();
104104

src/librustc_codegen_llvm/intrinsic.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#![allow(non_upper_case_globals)]
1212

13+
use attributes;
1314
use intrinsics::{self, Intrinsic};
1415
use llvm::{self, TypeKind};
1516
use abi::{Abi, FnType, LlvmType, PassMode};
@@ -944,6 +945,7 @@ fn gen_fn<'ll, 'tcx>(
944945
Abi::Rust
945946
)));
946947
let llfn = declare::define_internal_fn(cx, name, rust_fn_ty);
948+
attributes::from_fn_attrs(cx, llfn, None);
947949
let bx = Builder::new_block(cx, llfn, "entry-block");
948950
codegen(bx);
949951
llfn

src/librustc_codegen_llvm/mono_item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
182182
if instance.def.is_inline(cx.tcx) {
183183
attributes::inline(lldecl, attributes::InlineAttr::Hint);
184184
}
185-
attributes::from_fn_attrs(cx, lldecl, instance.def.def_id());
185+
attributes::from_fn_attrs(cx, lldecl, Some(instance.def.def_id()));
186186

187187
cx.instances.borrow_mut().insert(instance, lldecl);
188188
}

0 commit comments

Comments
 (0)