Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trans: Re-enable unwinding on 64-bit MSVC #27676

Merged
merged 1 commit into from
Aug 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,10 @@ CTEST_DISABLE_debuginfo-gdb =
CTEST_DISABLE_debuginfo-lldb = "lldb tests are disabled on android"
endif

ifeq ($(findstring msvc,$(CFG_TARGET)),msvc)
CTEST_DISABLE_debuginfo-gdb = "gdb tests are disabled on MSVC"
endif

# CTEST_DISABLE_NONSELFHOST_$(TEST_GROUP), if set, will cause that
# test group to be disabled *unless* the target is able to build a
# compiler (i.e. when the target triple is in the set of of host
Expand Down Expand Up @@ -1050,7 +1054,8 @@ $(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
$$(MAKE) \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
$(3)/test/run-make/$$* \
"$$(CC_$(3)) $$(CFG_GCCISH_CFLAGS_$(3))" \
$$(CC_$(3)) \
"$$(CFG_GCCISH_CFLAGS_$(3))" \
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
"$$(TESTNAME)" \
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3)) \
Expand Down
16 changes: 8 additions & 8 deletions src/etc/maketest.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ def convert_path_spec(name, value):
make = sys.argv[2]
putenv('RUSTC', os.path.abspath(sys.argv[3]))
putenv('TMPDIR', os.path.abspath(sys.argv[4]))
putenv('CC', sys.argv[5])
putenv('RUSTDOC', os.path.abspath(sys.argv[6]))
filt = sys.argv[7]
putenv('LD_LIB_PATH_ENVVAR', sys.argv[8])
putenv('HOST_RPATH_DIR', os.path.abspath(sys.argv[9]))
putenv('TARGET_RPATH_DIR', os.path.abspath(sys.argv[10]))
putenv('RUST_BUILD_STAGE', sys.argv[11])
putenv('S', os.path.abspath(sys.argv[12]))
putenv('CC', sys.argv[5] + ' ' + sys.argv[6])
putenv('RUSTDOC', os.path.abspath(sys.argv[7]))
filt = sys.argv[8]
putenv('LD_LIB_PATH_ENVVAR', sys.argv[9])
putenv('HOST_RPATH_DIR', os.path.abspath(sys.argv[10]))
putenv('TARGET_RPATH_DIR', os.path.abspath(sys.argv[11]))
putenv('RUST_BUILD_STAGE', sys.argv[12])
putenv('S', os.path.abspath(sys.argv[13]))
putenv('PYTHON', sys.executable)

if filt not in sys.argv[1]:
Expand Down
13 changes: 13 additions & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,18 @@ mod rustc {
pub use lint;
}

// FIXME(#27438): right now the unit tests of librustc don't refer to any actual
// functions generated in librustc_data_structures (all
// references are through generic functions), but statics are
// referenced from time to time. Due to this bug we won't
// actually correctly link in the statics unless we also
// reference a function, so be sure to reference a dummy
// function.
#[test]
fn noop() {
rustc_data_structures::__noop_fix_for_27438();
}


// Build the diagnostics array at the end so that the metadata includes error use sites.
__build_diagnostic_array! { librustc, DIAGNOSTICS }
1 change: 1 addition & 0 deletions src/librustc_back/target/x86_64_pc_windows_msvc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use target::Target;
pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts();
base.cpu = "x86-64".to_string();
base.custom_unwind_resume = true;

Target {
llvm_target: "x86_64-pc-windows-msvc".to_string(),
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ pub mod graph;
pub mod bitvec;
pub mod ivar;
pub mod unify;

// See comments in src/librustc/lib.rs
#[doc(hidden)]
pub fn __noop_fix_for_27438() {}
21 changes: 15 additions & 6 deletions src/librustc_trans/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,13 +745,22 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}

/// Returns whether this session's target will use SEH-based unwinding.
///
/// This is only true for MSVC targets, and even then the 64-bit MSVC target
/// currently uses SEH-ish unwinding with DWARF info tables to the side (same as
/// 64-bit MinGW) instead of "full SEH".
pub fn wants_msvc_seh(sess: &Session) -> bool {
sess.target.target.options.is_like_msvc && sess.target.target.arch == "x86"
}

pub fn need_invoke(bcx: Block) -> bool {
// FIXME(#25869) currently unwinding is not implemented for MSVC and our
// normal unwinding infrastructure ends up just causing linker
// errors with the current LLVM implementation, so landing
// pads are disabled entirely for MSVC targets
if bcx.sess().no_landing_pads() ||
bcx.sess().target.target.options.is_like_msvc {
// FIXME(#25869) currently SEH-based unwinding is pretty buggy in LLVM and
// is being overhauled as this is being written. Until that
// time such that upstream LLVM's implementation is more solid
// and we start binding it we need to skip invokes for any
// target which wants SEH-based unwinding.
if bcx.sess().no_landing_pads() || wants_msvc_seh(bcx.sess()) {
return false;
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
// landing pads as "landing pads for SEH".
let target = &self.ccx.sess().target.target;
match self.ccx.tcx().lang_items.eh_personality() {
Some(def_id) if !target.options.is_like_msvc => {
Some(def_id) if !base::wants_msvc_seh(self.ccx.sess()) => {
callee::trans_fn_ref(self.ccx, def_id, ExprId(0),
self.param_substs).val
}
Expand All @@ -604,7 +604,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
match *personality {
Some(llpersonality) => llpersonality,
None => {
let name = if !target.options.is_like_msvc {
let name = if !base::wants_msvc_seh(self.ccx.sess()) {
"rust_eh_personality"
} else if target.arch == "x86" {
"_except_handler3"
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/trans/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ fn try_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
Call(bcx, func, &[data], None, dloc);
Store(bcx, C_null(Type::i8p(bcx.ccx())), dest);
bcx
} else if bcx.sess().target.target.options.is_like_msvc {
} else if wants_msvc_seh(bcx.sess()) {
trans_msvc_try(bcx, func, data, dest, dloc)
} else {
trans_gnu_try(bcx, func, data, dest, dloc)
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/rt/unwind/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ use sys_common::mutex::Mutex;
// implementations. One goes through SEH on Windows and the other goes through
// libgcc via the libunwind-like API.

// *-pc-windows-msvc
#[cfg(all(windows, target_env = "msvc"))]
// i686-pc-windows-msvc
#[cfg(all(windows, target_arch = "x86", target_env = "msvc"))]
#[path = "seh.rs"] #[doc(hidden)]
pub mod imp;

// x86_64-pc-windows-gnu
#[cfg(all(windows, target_arch="x86_64", target_env="gnu"))]
// x86_64-pc-windows-*
#[cfg(all(windows, target_arch = "x86_64"))]
#[path = "seh64_gnu.rs"] #[doc(hidden)]
pub mod imp;

// i686-pc-windows-gnu and all others
#[cfg(any(unix, all(windows, target_arch="x86", target_env="gnu")))]
#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))]
#[path = "gcc.rs"] #[doc(hidden)]
pub mod imp;

Expand Down