Skip to content

Commit 9eff77a

Browse files
committed
rewrite foreign-double-unwind to rmake
1 parent 2d5a628 commit 9eff77a

File tree

8 files changed

+131
-15
lines changed

8 files changed

+131
-15
lines changed

src/tools/cargo

Submodule cargo updated 111 files

src/tools/run-make-support/src/external_deps/c_build.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
use std::path::PathBuf;
22

3+
<<<<<<< HEAD
34
use super::cygpath::get_windows_path;
45
use crate::artifact_names::{dynamic_lib_name, static_lib_name};
56
use crate::external_deps::cc::cc;
7+
=======
8+
use crate::artifact_names::static_lib_name;
9+
use crate::external_deps::cc::{cc, cxx};
10+
>>>>>>> e3cf7e53339 (rewrite foreign-double-unwind to rmake)
611
use crate::external_deps::llvm::llvm_ar;
712
use crate::path_helpers::path;
813
use crate::targets::{is_darwin, is_msvc, is_windows};
914

1015
// FIXME(Oneirical): These native build functions should take a Path-based generic.
1116

1217
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
18+
/// Built from a C file.
1319
#[track_caller]
1420
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
1521
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
@@ -58,3 +64,24 @@ pub fn build_native_dynamic_lib(lib_name: &str) -> PathBuf {
5864
}
5965
path(lib_path)
6066
}
67+
68+
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
69+
/// Built from a C++ file.
70+
#[track_caller]
71+
pub fn build_native_static_lib_cxx(lib_name: &str) -> PathBuf {
72+
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
73+
let src = format!("{lib_name}.cpp");
74+
let lib_path = static_lib_name(lib_name);
75+
if is_msvc() {
76+
cxx().arg("-EHs").arg("-c").out_exe(&obj_file).input(src).run();
77+
} else {
78+
cxx().arg("-c").out_exe(&obj_file).input(src).run();
79+
};
80+
let obj_file = if is_msvc() {
81+
PathBuf::from(format!("{lib_name}.obj"))
82+
} else {
83+
PathBuf::from(format!("{lib_name}.o"))
84+
};
85+
llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
86+
path(lib_path)
87+
}

src/tools/run-make-support/src/external_deps/cc.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,41 @@ pub fn extra_cxx_flags() -> Vec<&'static str> {
215215
}
216216
}
217217
}
218+
219+
/// `EXTRARSCXXFLAGS`
220+
pub fn extra_rs_cxx_flags() -> Vec<&'static str> {
221+
// Adapted from tools.mk (trimmed):
222+
//
223+
// ```makefile
224+
// ifdef IS_WINDOWS
225+
// ifdef IS_MSVC
226+
// else
227+
// EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++
228+
// endif
229+
// else
230+
// ifeq ($(UNAME),Darwin)
231+
// EXTRARSCXXFLAGS := -lc++
232+
// else
233+
// ifeq ($(UNAME),FreeBSD)
234+
// else
235+
// ifeq ($(UNAME),SunOS)
236+
// else
237+
// ifeq ($(UNAME),OpenBSD)
238+
// else
239+
// EXTRARSCXXFLAGS := -lstdc++
240+
// endif
241+
// endif
242+
// endif
243+
// endif
244+
// endif
245+
// ```
246+
if is_windows() {
247+
if is_msvc() { vec![] } else { vec!["-lstatic:-bundle=stdc++"] }
248+
} else {
249+
match &uname()[..] {
250+
"Darwin" => vec!["-lc++"],
251+
"FreeBSD" | "SunOS" | "OpenBSD" => vec![],
252+
_ => vec!["-lstdc++"],
253+
}
254+
}
255+
}

src/tools/run-make-support/src/external_deps/rustc.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::command::Command;
55
use crate::env::env_var;
66
use crate::path_helpers::cwd;
77
use crate::util::set_host_rpath;
8+
use crate::{is_msvc, is_windows, uname};
89

910
/// Construct a new `rustc` invocation. This will automatically set the library
1011
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
@@ -314,4 +315,46 @@ impl Rustc {
314315
self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
315316
self
316317
}
318+
319+
/// `EXTRARSCXXFLAGS`
320+
pub fn extra_rs_cxx_flags(&mut self) -> &mut Self {
321+
// Adapted from tools.mk (trimmed):
322+
//
323+
// ```makefile
324+
// ifdef IS_WINDOWS
325+
// ifdef IS_MSVC
326+
// else
327+
// EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++
328+
// endif
329+
// else
330+
// ifeq ($(UNAME),Darwin)
331+
// EXTRARSCXXFLAGS := -lc++
332+
// else
333+
// ifeq ($(UNAME),FreeBSD)
334+
// else
335+
// ifeq ($(UNAME),SunOS)
336+
// else
337+
// ifeq ($(UNAME),OpenBSD)
338+
// else
339+
// EXTRARSCXXFLAGS := -lstdc++
340+
// endif
341+
// endif
342+
// endif
343+
// endif
344+
// endif
345+
// ```
346+
let flag = if is_windows() {
347+
if is_msvc() { None } else { Some("-lstatic:-bundle=stdc++") }
348+
} else {
349+
match &uname()[..] {
350+
"Darwin" => Some("-lc++"),
351+
"FreeBSD" | "SunOS" | "OpenBSD" => None,
352+
_ => Some("-lstdc++"),
353+
}
354+
};
355+
if let Some(flag) = flag {
356+
self.cmd.arg(flag);
357+
}
358+
self
359+
}
317360
}

src/tools/run-make-support/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ pub use wasmparser;
4343
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
4444

4545
// These rely on external dependencies.
46-
pub use c_build::{build_native_dynamic_lib, build_native_static_lib};
4746
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
47+
pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx};
4848
pub use clang::{clang, Clang};
4949
pub use htmldocck::htmldocck;
5050
pub use llvm::{

src/tools/tidy/src/allowed_run_make_makefiles.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ run-make/emit-to-stdout/Makefile
1313
run-make/export-executable-symbols/Makefile
1414
run-make/extern-fn-reachable/Makefile
1515
run-make/fmt-write-bloat/Makefile
16-
run-make/foreign-double-unwind/Makefile
1716
run-make/foreign-exceptions/Makefile
1817
run-make/foreign-rust-exceptions/Makefile
1918
run-make/incr-add-rust-src-component/Makefile

tests/run-make/foreign-double-unwind/Makefile

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// When using foreign function interface (FFI) with C++, it is possible
2+
// to run into a "double unwind" if either both Rust and C++ run into a panic
3+
// and exception at the same time, or C++ encounters two exceptions. In this case,
4+
// one of the panic unwinds would be leaked and the other would be kept, leading
5+
// to undefined behaviour. After this was fixed in #92911, this test checks that
6+
// the keyword "unreachable" indicative of this bug triggering in this specific context
7+
// does not appear after successfully compiling and executing the program.
8+
// See https://github.com/rust-lang/rust/pull/92911
9+
10+
//@ needs-unwind
11+
// Reason: this test exercises panic unwinding
12+
//@ ignore-cross-compile
13+
// Reason: the compiled binary is executed
14+
15+
use run_make_support::{build_native_static_lib_cxx, run, rustc};
16+
17+
fn main() {
18+
build_native_static_lib_cxx("foo");
19+
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
20+
run("foo").assert_stdout_not_contains("unreachable");
21+
}

0 commit comments

Comments
 (0)