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

Disable unwinding for emscripten again #95950

Closed
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
21 changes: 0 additions & 21 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ pub struct CodegenCx<'ll, 'tcx> {
pub dbg_cx: Option<debuginfo::CodegenUnitDebugContext<'ll, 'tcx>>,

eh_personality: Cell<Option<&'ll Value>>,
eh_catch_typeinfo: Cell<Option<&'ll Value>>,
pub rust_try_fn: Cell<Option<(&'ll Type, &'ll Value)>>,

intrinsics: RefCell<FxHashMap<&'static str, (&'ll Type, &'ll Value)>>,
Expand Down Expand Up @@ -439,7 +438,6 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
coverage_cx,
dbg_cx,
eh_personality: Cell::new(None),
eh_catch_typeinfo: Cell::new(None),
rust_try_fn: Cell::new(None),
intrinsics: Default::default(),
local_gen_sym_counter: Cell::new(0),
Expand Down Expand Up @@ -889,25 +887,6 @@ impl<'ll> CodegenCx<'ll, '_> {
}
None
}

pub(crate) fn eh_catch_typeinfo(&self) -> &'ll Value {
if let Some(eh_catch_typeinfo) = self.eh_catch_typeinfo.get() {
return eh_catch_typeinfo;
}
let tcx = self.tcx;
assert!(self.sess().target.is_like_emscripten);
let eh_catch_typeinfo = match tcx.lang_items().eh_catch_typeinfo() {
Some(def_id) => self.get_static(def_id),
_ => {
let ty = self
.type_struct(&[self.type_ptr_to(self.type_isize()), self.type_i8p()], false);
self.declare_global("rust_eh_catch_typeinfo", ty)
}
};
let eh_catch_typeinfo = self.const_bitcast(eh_catch_typeinfo, self.type_i8p());
self.eh_catch_typeinfo.set(Some(eh_catch_typeinfo));
eh_catch_typeinfo
}
}

impl CodegenCx<'_, '_> {
Expand Down
87 changes: 0 additions & 87 deletions compiler/rustc_codegen_llvm/src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,6 @@ fn try_intrinsic<'ll>(
bx.store(bx.const_i32(0), dest, ret_align);
} else if wants_msvc_seh(bx.sess()) {
codegen_msvc_try(bx, try_func, data, catch_func, dest);
} else if bx.sess().target.is_like_emscripten {
codegen_emcc_try(bx, try_func, data, catch_func, dest);
} else {
codegen_gnu_try(bx, try_func, data, catch_func, dest);
}
Expand Down Expand Up @@ -656,91 +654,6 @@ fn codegen_gnu_try<'ll>(
bx.store(ret, dest, i32_align);
}

// Variant of codegen_gnu_try used for emscripten where Rust panics are
// implemented using C++ exceptions. Here we use exceptions of a specific type
// (`struct rust_panic`) to represent Rust panics.
fn codegen_emcc_try<'ll>(
bx: &mut Builder<'_, 'll, '_>,
try_func: &'ll Value,
data: &'ll Value,
catch_func: &'ll Value,
dest: &'ll Value,
) {
let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
// Codegens the shims described above:
//
// bx:
// invoke %try_func(%data) normal %normal unwind %catch
//
// normal:
// ret 0
//
// catch:
// (%ptr, %selector) = landingpad
// %rust_typeid = @llvm.eh.typeid.for(@_ZTI10rust_panic)
// %is_rust_panic = %selector == %rust_typeid
// %catch_data = alloca { i8*, i8 }
// %catch_data[0] = %ptr
// %catch_data[1] = %is_rust_panic
// call %catch_func(%data, %catch_data)
// ret 1
let then = bx.append_sibling_block("then");
let catch = bx.append_sibling_block("catch");

let try_func = llvm::get_param(bx.llfn(), 0);
let data = llvm::get_param(bx.llfn(), 1);
let catch_func = llvm::get_param(bx.llfn(), 2);
let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
bx.invoke(try_func_ty, try_func, &[data], then, catch, None);

bx.switch_to_block(then);
bx.ret(bx.const_i32(0));

// Type indicator for the exception being thrown.
//
// The first value in this tuple is a pointer to the exception object
// being thrown. The second value is a "selector" indicating which of
// the landing pad clauses the exception's type had been matched to.
bx.switch_to_block(catch);
let tydesc = bx.eh_catch_typeinfo();
let lpad_ty = bx.type_struct(&[bx.type_i8p(), bx.type_i32()], false);
let vals = bx.landing_pad(lpad_ty, bx.eh_personality(), 2);
bx.add_clause(vals, tydesc);
bx.add_clause(vals, bx.const_null(bx.type_i8p()));
let ptr = bx.extract_value(vals, 0);
let selector = bx.extract_value(vals, 1);

// Check if the typeid we got is the one for a Rust panic.
let rust_typeid = bx.call_intrinsic("llvm.eh.typeid.for", &[tydesc]);
let is_rust_panic = bx.icmp(IntPredicate::IntEQ, selector, rust_typeid);
let is_rust_panic = bx.zext(is_rust_panic, bx.type_bool());

// We need to pass two values to catch_func (ptr and is_rust_panic), so
// create an alloca and pass a pointer to that.
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
let i8_align = bx.tcx().data_layout.i8_align.abi;
let catch_data_type = bx.type_struct(&[bx.type_i8p(), bx.type_bool()], false);
let catch_data = bx.alloca(catch_data_type, ptr_align);
let catch_data_0 =
bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(0)]);
bx.store(ptr, catch_data_0, ptr_align);
let catch_data_1 =
bx.inbounds_gep(catch_data_type, catch_data, &[bx.const_usize(0), bx.const_usize(1)]);
bx.store(is_rust_panic, catch_data_1, i8_align);
let catch_data = bx.bitcast(catch_data, bx.type_i8p());

let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
bx.call(catch_ty, catch_func, &[data, catch_data], None);
bx.ret(bx.const_i32(1));
});

// Note that no invoke is used here because by definition this function
// can't panic (that's what it's catching).
let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None);
let i32_align = bx.tcx().data_layout.i32_align.abi;
bx.store(ret, dest, i32_align);
}

// Helper function to give a Block to a closure to codegen a shim function.
// This is currently primarily used for the `try` intrinsic functions above.
fn gen_fn<'ll, 'tcx>(
Expand Down
6 changes: 1 addition & 5 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_middle::bug;
use rustc_session::config::PrintRequest;
use rustc_session::Session;
use rustc_span::symbol::Symbol;
use rustc_target::spec::{MergeFunctions, PanicStrategy};
use rustc_target::spec::MergeFunctions;
use smallvec::{smallvec, SmallVec};
use std::ffi::{CStr, CString};
use tracing::debug;
Expand Down Expand Up @@ -109,10 +109,6 @@ unsafe fn configure_llvm(sess: &Session) {
}
}

if sess.target.os == "emscripten" && sess.panic_strategy() == PanicStrategy::Unwind {
add("-enable-emscripten-cxx-exceptions", false);
}

// HACK(eddyb) LLVM inserts `llvm.assume` calls to preserve align attributes
// during inlining. Unfortunately these may block other optimizations.
add("-preserve-alignment-assumptions-during-inlining=false", false);
Expand Down
11 changes: 1 addition & 10 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use rustc_span::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile;
use rustc_target::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target};
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, Target};

use super::archive::{find_library, ArchiveBuilder};
use super::command::Command;
Expand Down Expand Up @@ -2047,15 +2047,6 @@ fn add_order_independent_options(
cmd.no_crt_objects();
}

if sess.target.is_like_emscripten {
cmd.arg("-s");
cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort {
"DISABLE_EXCEPTION_CATCHING=1"
} else {
"DISABLE_EXCEPTION_CATCHING=0"
});
}

if flavor == LinkerFlavor::PtxLinker {
// Provide the linker with fallback to internal `target-cpu`.
cmd.arg("--fallback-arch");
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,6 @@ language_item_table! {
Start, sym::start, start_fn, Target::Fn, GenericRequirement::Exact(1);

EhPersonality, sym::eh_personality, eh_personality, Target::Fn, GenericRequirement::None;
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;

OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1);

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir/src/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,5 @@ impl LanguageItems {
weak_lang_items! {
panic_impl, PanicImpl, rust_begin_unwind;
eh_personality, EhPersonality, rust_eh_personality;
eh_catch_typeinfo, EhCatchTypeinfo, rust_eh_catch_typeinfo;
oom, Oom, rust_oom;
}
4 changes: 1 addition & 3 deletions compiler/rustc_middle/src/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ pub fn required(tcx: TyCtxt<'_>, lang_item: LangItem) -> bool {
// symbols. Other panic runtimes ensure that the relevant symbols are
// available to link things together, but they're never exercised.
match tcx.sess.panic_strategy() {
PanicStrategy::Abort => {
lang_item != LangItem::EhPersonality && lang_item != LangItem::EhCatchTypeinfo
}
PanicStrategy::Abort => lang_item != LangItem::EhPersonality,
PanicStrategy::Unwind => true,
}
}
3 changes: 0 additions & 3 deletions compiler/rustc_passes/src/weak_lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItem
if items.eh_personality().is_none() {
items.missing.push(LangItem::EhPersonality);
}
if tcx.sess.target.is_like_emscripten && items.eh_catch_typeinfo().is_none() {
items.missing.push(LangItem::EhCatchTypeinfo);
}

let crate_items = tcx.hir_crate_items(());
for id in crate_items.foreign_items() {
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,6 @@ symbols! {
e,
edition_macro_pats,
edition_panic,
eh_catch_typeinfo,
eh_personality,
emit_enum,
emit_enum_variant,
Expand Down Expand Up @@ -1164,7 +1163,6 @@ symbols! {
rust_2024_preview,
rust_begin_unwind,
rust_cold_cc,
rust_eh_catch_typeinfo,
rust_eh_personality,
rust_eh_register_frames,
rust_eh_unregister_frames,
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_target/src/spec/wasm32_unknown_emscripten.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{cvs, wasm_base};
use super::{LinkArgs, LinkerFlavor, PanicStrategy, Target, TargetOptions};
use super::{LinkArgs, LinkerFlavor, Target, TargetOptions};

pub fn target() -> Target {
let mut options = wasm_base::options();
Expand All @@ -16,7 +16,7 @@ pub fn target() -> Target {
let mut post_link_args = LinkArgs::new();
post_link_args.insert(
LinkerFlavor::Em,
vec!["-sABORTING_MALLOC=0".into(), "-Wl,--fatal-warnings".into()],
vec!["-s".into(), "ABORTING_MALLOC=0".into(), "-Wl,--fatal-warnings".into()],
);

let opts = TargetOptions {
Expand All @@ -27,7 +27,6 @@ pub fn target() -> Target {
exe_suffix: ".js".into(),
linker: None,
is_like_emscripten: true,
panic_strategy: PanicStrategy::Unwind,
post_link_args,
families: cvs!["unix", "wasm"],
..options
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/collections/binary_heap/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ fn test_drain_sorted() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_drain_sorted_leak() {
static DROPS: AtomicU32 = AtomicU32::new(0);

Expand Down Expand Up @@ -411,9 +412,8 @@ fn test_retain() {
// even if the order might not be correct.
//
// Destructors must be called exactly once per element.
// FIXME: re-enable emscripten once it can unwind again
#[test]
#[cfg(not(target_os = "emscripten"))]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn panic_safe() {
use rand::{seq::SliceRandom, thread_rng};
use std::cmp;
Expand Down
9 changes: 9 additions & 0 deletions library/alloc/src/collections/btree/map/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,7 @@ mod test_drain_filter {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn drop_panic_leak() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand All @@ -1142,6 +1143,7 @@ mod test_drain_filter {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn pred_panic_leak() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand All @@ -1168,6 +1170,7 @@ mod test_drain_filter {

// Same as above, but attempt to use the iterator again after the panic in the predicate
#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn pred_panic_reuse() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand Down Expand Up @@ -1416,6 +1419,7 @@ fn test_clear() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_clear_drop_panic_leak() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand Down Expand Up @@ -1507,11 +1511,13 @@ fn test_clone_panic_leak(size: usize) {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_clone_panic_leak_height_0() {
test_clone_panic_leak(3)
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_clone_panic_leak_height_1() {
test_clone_panic_leak(MIN_INSERTS_HEIGHT_1)
}
Expand Down Expand Up @@ -2066,6 +2072,7 @@ create_append_test!(test_append_239, 239);
create_append_test!(test_append_1700, 1700);

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_append_drop_leak() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand Down Expand Up @@ -2207,6 +2214,7 @@ fn test_split_off_large_random_sorted() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_into_iter_drop_leak_height_0() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand All @@ -2230,6 +2238,7 @@ fn test_into_iter_drop_leak_height_0() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_into_iter_drop_leak_height_1() {
let size = MIN_INSERTS_HEIGHT_1;
for panic_point in vec![0, 1, size - 2, size - 1] {
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/collections/btree/set/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ fn test_drain_filter() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_drain_filter_drop_panic_leak() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand All @@ -397,6 +398,7 @@ fn test_drain_filter_drop_panic_leak() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_drain_filter_pred_panic_leak() {
let a = CrashTestDummy::new(0);
let b = CrashTestDummy::new(1);
Expand Down
3 changes: 3 additions & 0 deletions library/alloc/src/collections/linked_list/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -983,6 +983,7 @@ fn drain_filter_complex() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn drain_filter_drop_panic_leak() {
static mut DROPS: i32 = 0;

Expand Down Expand Up @@ -1017,6 +1018,7 @@ fn drain_filter_drop_panic_leak() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn drain_filter_pred_panic_leak() {
static mut DROPS: i32 = 0;

Expand Down Expand Up @@ -1123,6 +1125,7 @@ fn test_drop_clear() {
}

#[test]
#[cfg_attr(not(panic = "unwind"), should_panic)]
fn test_drop_panic() {
static mut DROPS: i32 = 0;

Expand Down
Loading