mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
rustc_trans: Disable landing pads on 32-bit MSVC
This is currently quite buggy in LLVM from what I can tell, so just disable it entirely. This commit also adds preliminary support, however, to actually target 32-bit MSVC by making sure the `rust_try_msvc_32.ll` file exists and wiring up exceptions to `_except_handler3` instead of `__C_specific_handler` (which doesn't exist on 32-bit).
This commit is contained in:
parent
83ee47b054
commit
3e26e56a79
@ -752,7 +752,14 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
pub fn need_invoke(bcx: Block) -> bool {
|
||||
if bcx.sess().no_landing_pads() {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
// Currently 32-bit MSVC unwinding is not super well implemented in LLVM, so
|
||||
// we avoid it entirely.
|
||||
if bcx.sess().target.target.options.is_like_msvc &&
|
||||
bcx.sess().target.target.arch == "x86" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Avoid using invoke if we are already inside a landing pad.
|
||||
|
@ -851,8 +851,8 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||
// an "exception", but for MSVC we want to force SEH. This means that we
|
||||
// can't actually have the personality function be our standard
|
||||
// `rust_eh_personality` function, but rather we wired it up to the
|
||||
// CRT's custom `__C_specific_handler` personality funciton, which
|
||||
// forces LLVM to consider landing pads as "landing pads for SEH".
|
||||
// CRT's custom personality function, which forces LLVM to consider
|
||||
// landing pads as "landing pads for SEH".
|
||||
let target = &self.ccx.sess().target.target;
|
||||
let llpersonality = match pad_bcx.tcx().lang_items.eh_personality() {
|
||||
Some(def_id) if !target.options.is_like_msvc => {
|
||||
@ -864,10 +864,12 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
|
||||
match *personality {
|
||||
Some(llpersonality) => llpersonality,
|
||||
None => {
|
||||
let name = if target.options.is_like_msvc {
|
||||
"__C_specific_handler"
|
||||
} else {
|
||||
let name = if !target.options.is_like_msvc {
|
||||
"rust_eh_personality"
|
||||
} else if target.arch == "x86" {
|
||||
"_except_handler3"
|
||||
} else {
|
||||
"__C_specific_handler"
|
||||
};
|
||||
let fty = Type::variadic_func(&[], &Type::i32(self.ccx));
|
||||
let f = declare::declare_cfn(self.ccx, name, fty,
|
||||
|
42
src/rt/rust_try_msvc_32.ll
Normal file
42
src/rt/rust_try_msvc_32.ll
Normal file
@ -0,0 +1,42 @@
|
||||
; Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
; file at the top-level directory of this distribution and at
|
||||
; http://rust-lang.org/COPYRIGHT.
|
||||
;
|
||||
; Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
; http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
; <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
; option. This file may not be copied, modified, or distributed
|
||||
; except according to those terms.
|
||||
|
||||
; For more comments about what's going on here see rust_try_msvc_64.ll. The only
|
||||
; difference between that and this file is the personality function used as it's
|
||||
; different for 32-bit MSVC than it is for 64-bit.
|
||||
|
||||
define i8* @rust_try(void (i8*)* %f, i8* %env)
|
||||
personality i8* bitcast (i32 (...)* @_except_handler3 to i8*)
|
||||
{
|
||||
invoke void %f(i8* %env)
|
||||
to label %normal
|
||||
unwind label %catch
|
||||
|
||||
normal:
|
||||
ret i8* null
|
||||
catch:
|
||||
%vals = landingpad { i8*, i32 }
|
||||
catch i8* bitcast (i32 (i8*, i8*)* @__rust_try_filter to i8*)
|
||||
%ehptr = extractvalue { i8*, i32 } %vals, 0
|
||||
%sel = extractvalue { i8*, i32 } %vals, 1
|
||||
%filter_sel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32 (i8*, i8*)* @__rust_try_filter to i8*))
|
||||
%is_filter = icmp eq i32 %sel, %filter_sel
|
||||
br i1 %is_filter, label %catch-return, label %catch-resume
|
||||
|
||||
catch-return:
|
||||
ret i8* %ehptr
|
||||
|
||||
catch-resume:
|
||||
resume { i8*, i32 } %vals
|
||||
}
|
||||
|
||||
declare i32 @_except_handler3(...)
|
||||
declare i32 @__rust_try_filter(i8*, i8*)
|
||||
declare i32 @llvm.eh.typeid.for(i8*) readnone nounwind
|
Loading…
Reference in New Issue
Block a user