11
11
12
12
use std:: ffi:: CString ;
13
13
14
- use rustc:: hir:: CodegenFnAttrFlags ;
14
+ use rustc:: hir:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
15
15
use rustc:: hir:: def_id:: { DefId , LOCAL_CRATE } ;
16
16
use rustc:: session:: Session ;
17
17
use rustc:: session:: config:: Sanitizer ;
@@ -134,11 +134,37 @@ pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
134
134
135
135
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
136
136
/// 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 ( ) ) ;
139
144
140
145
inline ( llfn, codegen_fn_attrs. inline ) ;
141
146
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
+
142
168
set_frame_pointer_elimination ( cx, llfn) ;
143
169
set_probestack ( cx, llfn) ;
144
170
@@ -162,7 +188,7 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
162
188
// *in Rust code* may unwind. Foreign items like `extern "C" {
163
189
// fn foo(); }` are assumed not to unwind **unless** they have
164
190
// 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 ) {
166
192
Some ( true )
167
193
} else {
168
194
None
@@ -208,14 +234,16 @@ pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
208
234
// Note that currently the `wasm-import-module` doesn't do anything, but
209
235
// eventually LLVM 7 should read this and ferry the appropriate import
210
236
// 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
+ }
219
247
}
220
248
}
221
249
}
0 commit comments