Skip to content

Commit b6b4f5a

Browse files
committed
trans: Re-enable unwinding on 64-bit MSVC
This commit leverages the runtime support for DWARF exception info added in #27210 to enable unwinding by default on 64-bit MSVC. This also additionally adds a few minor fixes here and there in the test harness and such to get `make check` entirely passing on 64-bit MSVC: * The invocation of `maketest.py` now works with spaces/quotes in CC * debuginfo tests are disabled on MSVC * A link error for librustc was hacked around (see #27438)
1 parent 91c618f commit b6b4f5a

File tree

9 files changed

+55
-23
lines changed

9 files changed

+55
-23
lines changed

mk/tests.mk

+6-1
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,10 @@ CTEST_DISABLE_debuginfo-gdb =
597597
CTEST_DISABLE_debuginfo-lldb = "lldb tests are disabled on android"
598598
endif
599599

600+
ifeq ($(findstring msvc,$(CFG_TARGET)),msvc)
601+
CTEST_DISABLE_debuginfo-gdb = "gdb tests are disabled on MSVC"
602+
endif
603+
600604
# CTEST_DISABLE_NONSELFHOST_$(TEST_GROUP), if set, will cause that
601605
# test group to be disabled *unless* the target is able to build a
602606
# compiler (i.e. when the target triple is in the set of of host
@@ -1050,7 +1054,8 @@ $(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
10501054
$$(MAKE) \
10511055
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
10521056
$(3)/test/run-make/$$* \
1053-
"$$(CC_$(3)) $$(CFG_GCCISH_CFLAGS_$(3))" \
1057+
$$(CC_$(3)) \
1058+
"$$(CFG_GCCISH_CFLAGS_$(3))" \
10541059
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
10551060
"$$(TESTNAME)" \
10561061
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3)) \

src/etc/maketest.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ def convert_path_spec(name, value):
4141
make = sys.argv[2]
4242
putenv('RUSTC', os.path.abspath(sys.argv[3]))
4343
putenv('TMPDIR', os.path.abspath(sys.argv[4]))
44-
putenv('CC', sys.argv[5])
45-
putenv('RUSTDOC', os.path.abspath(sys.argv[6]))
46-
filt = sys.argv[7]
47-
putenv('LD_LIB_PATH_ENVVAR', sys.argv[8])
48-
putenv('HOST_RPATH_DIR', os.path.abspath(sys.argv[9]))
49-
putenv('TARGET_RPATH_DIR', os.path.abspath(sys.argv[10]))
50-
putenv('RUST_BUILD_STAGE', sys.argv[11])
51-
putenv('S', os.path.abspath(sys.argv[12]))
44+
putenv('CC', sys.argv[5] + ' ' + sys.argv[6])
45+
putenv('RUSTDOC', os.path.abspath(sys.argv[7]))
46+
filt = sys.argv[8]
47+
putenv('LD_LIB_PATH_ENVVAR', sys.argv[9])
48+
putenv('HOST_RPATH_DIR', os.path.abspath(sys.argv[10]))
49+
putenv('TARGET_RPATH_DIR', os.path.abspath(sys.argv[11]))
50+
putenv('RUST_BUILD_STAGE', sys.argv[12])
51+
putenv('S', os.path.abspath(sys.argv[13]))
5252
putenv('PYTHON', sys.executable)
5353

5454
if filt not in sys.argv[1]:

src/librustc/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -179,5 +179,18 @@ mod rustc {
179179
pub use lint;
180180
}
181181

182+
// FIXME(#27438): right now the unit tests of librustc don't refer to any actual
183+
// functions generated in librustc_data_structures (all
184+
// references are through generic functions), but statics are
185+
// referenced from time to time. Due to this bug we won't
186+
// actually correctly link in the statics unless we also
187+
// reference a function, so be sure to reference a dummy
188+
// function.
189+
#[test]
190+
fn noop() {
191+
rustc_data_structures::__noop_fix_for_27438();
192+
}
193+
194+
182195
// Build the diagnostics array at the end so that the metadata includes error use sites.
183196
__build_diagnostic_array! { librustc, DIAGNOSTICS }

src/librustc_back/target/x86_64_pc_windows_msvc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use target::Target;
1313
pub fn target() -> Target {
1414
let mut base = super::windows_msvc_base::opts();
1515
base.cpu = "x86-64".to_string();
16+
base.custom_unwind_resume = true;
1617

1718
Target {
1819
llvm_target: "x86_64-pc-windows-msvc".to_string(),

src/librustc_data_structures/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@ pub mod graph;
3838
pub mod bitvec;
3939
pub mod ivar;
4040
pub mod unify;
41+
42+
// See comments in src/librustc/lib.rs
43+
#[doc(hidden)]
44+
pub fn __noop_fix_for_27438() {}

src/librustc_trans/trans/base.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -745,13 +745,22 @@ pub fn invoke<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
745745
}
746746
}
747747

748+
/// Returns whether this session's target will use SEH-based unwinding.
749+
///
750+
/// This is only true for MSVC targets, and even then the 64-bit MSVC target
751+
/// currently uses SEH-ish unwinding with DWARF info tables to the side (same as
752+
/// 64-bit MinGW) instead of "full SEH".
753+
pub fn wants_msvc_seh(sess: &Session) -> bool {
754+
sess.target.target.options.is_like_msvc && sess.target.target.arch == "x86"
755+
}
756+
748757
pub fn need_invoke(bcx: Block) -> bool {
749-
// FIXME(#25869) currently unwinding is not implemented for MSVC and our
750-
// normal unwinding infrastructure ends up just causing linker
751-
// errors with the current LLVM implementation, so landing
752-
// pads are disabled entirely for MSVC targets
753-
if bcx.sess().no_landing_pads() ||
754-
bcx.sess().target.target.options.is_like_msvc {
758+
// FIXME(#25869) currently SEH-based unwinding is pretty buggy in LLVM and
759+
// is being overhauled as this is being written. Until that
760+
// time such that upstream LLVM's implementation is more solid
761+
// and we start binding it we need to skip invokes for any
762+
// target which wants SEH-based unwinding.
763+
if bcx.sess().no_landing_pads() || wants_msvc_seh(bcx.sess()) {
755764
return false;
756765
}
757766

src/librustc_trans/trans/common.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
595595
// landing pads as "landing pads for SEH".
596596
let target = &self.ccx.sess().target.target;
597597
match self.ccx.tcx().lang_items.eh_personality() {
598-
Some(def_id) if !target.options.is_like_msvc => {
598+
Some(def_id) if !base::wants_msvc_seh(self.ccx.sess()) => {
599599
callee::trans_fn_ref(self.ccx, def_id, ExprId(0),
600600
self.param_substs).val
601601
}
@@ -604,7 +604,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
604604
match *personality {
605605
Some(llpersonality) => llpersonality,
606606
None => {
607-
let name = if !target.options.is_like_msvc {
607+
let name = if !base::wants_msvc_seh(self.ccx.sess()) {
608608
"rust_eh_personality"
609609
} else if target.arch == "x86" {
610610
"_except_handler3"

src/librustc_trans/trans/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ fn try_intrinsic<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
10371037
Call(bcx, func, &[data], None, dloc);
10381038
Store(bcx, C_null(Type::i8p(bcx.ccx())), dest);
10391039
bcx
1040-
} else if bcx.sess().target.target.options.is_like_msvc {
1040+
} else if wants_msvc_seh(bcx.sess()) {
10411041
trans_msvc_try(bcx, func, data, dest, dloc)
10421042
} else {
10431043
trans_gnu_try(bcx, func, data, dest, dloc)

src/libstd/rt/unwind/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,18 @@ use sys_common::mutex::Mutex;
7777
// implementations. One goes through SEH on Windows and the other goes through
7878
// libgcc via the libunwind-like API.
7979

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

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

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

0 commit comments

Comments
 (0)