about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-08-11 11:48:43 -0700
committerAlex Crichton <alex@alexcrichton.com>2015-08-11 16:45:02 -0700
commitb6b4f5a0e7a98d918d7c5a56e291c0063f257f1e (patch)
tree57ae604ac7138ac138d63cc38ed82ad4194d03a0
parent91c618f133a35ffccc7e03e06f9318c59d091ae3 (diff)
downloadrust-b6b4f5a0e7a98d918d7c5a56e291c0063f257f1e.tar.gz
rust-b6b4f5a0e7a98d918d7c5a56e291c0063f257f1e.zip
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)
-rw-r--r--mk/tests.mk7
-rw-r--r--src/etc/maketest.py16
-rw-r--r--src/librustc/lib.rs13
-rw-r--r--src/librustc_back/target/x86_64_pc_windows_msvc.rs1
-rw-r--r--src/librustc_data_structures/lib.rs4
-rw-r--r--src/librustc_trans/trans/base.rs21
-rw-r--r--src/librustc_trans/trans/common.rs4
-rw-r--r--src/librustc_trans/trans/intrinsic.rs2
-rw-r--r--src/libstd/rt/unwind/mod.rs10
9 files changed, 55 insertions, 23 deletions
diff --git a/mk/tests.mk b/mk/tests.mk
index 28837e05195..f91828838a8 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -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
@@ -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)) \
diff --git a/src/etc/maketest.py b/src/etc/maketest.py
index f500de5e15d..04bf81a96aa 100644
--- a/src/etc/maketest.py
+++ b/src/etc/maketest.py
@@ -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]:
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index bb44abc4f07..935f75040ef 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -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 }
diff --git a/src/librustc_back/target/x86_64_pc_windows_msvc.rs b/src/librustc_back/target/x86_64_pc_windows_msvc.rs
index addaaeb1b63..85756db9606 100644
--- a/src/librustc_back/target/x86_64_pc_windows_msvc.rs
+++ b/src/librustc_back/target/x86_64_pc_windows_msvc.rs
@@ -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(),
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 558d15610df..b056ec2cb05 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -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() {}
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 716b1290817..947c902b2a9 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -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;
     }
 
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index f57612789b5..98301221f96 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -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
             }
@@ -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"
diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs
index 0400771dff1..293a0a6a4ca 100644
--- a/src/librustc_trans/trans/intrinsic.rs
+++ b/src/librustc_trans/trans/intrinsic.rs
@@ -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)
diff --git a/src/libstd/rt/unwind/mod.rs b/src/libstd/rt/unwind/mod.rs
index bb43eec8db1..4feb2d49a98 100644
--- a/src/libstd/rt/unwind/mod.rs
+++ b/src/libstd/rt/unwind/mod.rs
@@ -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;