Skip to content

Commit aca198c

Browse files
committed
[WebAssembly] Error out when Emscripten SjLj setjmp is used with Wasm EH
Currently, when Wasm EH is used with Emscripten SjLj, Emscripten SjLj cannot handle `invoke` instructions - it assumes all `invoke`s have been lowered away with Emscripten EH. But in Wasm EH they are lowered in instruction selection, so they are still present in the IR stage. This happens when 1. Wasm EH and Emscripten SjLj are used together 2. A function that calls `setjmp` uses exceptions, i.e., has `invoke`s We were already erroring out with an assertion failure in this case, but this CL makes it error out more properly with a valid error message. Wasm EH + Wasm SjLj will not have this restrictions. (it will have another restriction though, e.g., `setjmp` cannot be called within `catch`. But why would anyone do that..) Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D107687
1 parent bf6000d commit aca198c

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1105,7 +1105,10 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
11051105
for (unsigned I = 0; I < BBs.size(); I++) {
11061106
BasicBlock *BB = BBs[I];
11071107
for (Instruction &I : *BB) {
1108-
assert(!isa<InvokeInst>(&I));
1108+
if (isa<InvokeInst>(&I))
1109+
report_fatal_error("When using Wasm EH with Emscripten SjLj, there is "
1110+
"a restriction that `setjmp` function call and "
1111+
"exception cannot be used within the same function");
11091112
auto *CI = dyn_cast<CallInst>(&I);
11101113
if (!CI)
11111114
continue;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
; RUN: not --crash llc < %s -enable-emscripten-sjlj -exception-model=wasm 2>&1 | FileCheck %s
2+
3+
target triple = "wasm32-unknown-unknown"
4+
5+
%struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] }
6+
7+
define void @wasm_eh_emscripten_sjlj_error() personality i8* bitcast (i32 (...)* @__gxx_wasm_personality_v0 to i8*) {
8+
entry:
9+
%buf = alloca [1 x %struct.__jmp_buf_tag], align 16
10+
%arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
11+
%call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0
12+
%arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
13+
br label %bb
14+
15+
bb:
16+
invoke void @foo()
17+
to label %try.cont unwind label %catch.dispatch
18+
19+
catch.dispatch: ; preds = %entry
20+
%0 = catchswitch within none [label %catch.start] unwind to caller
21+
22+
catch.start: ; preds = %catch.dispatch
23+
%1 = catchpad within %0 [i8* null]
24+
%2 = call i8* @llvm.wasm.get.exception(token %1)
25+
%3 = call i32 @llvm.wasm.get.ehselector(token %1)
26+
%4 = call i8* @__cxa_begin_catch(i8* %2) #2 [ "funclet"(token %1) ]
27+
call void @__cxa_end_catch() [ "funclet"(token %1) ]
28+
catchret from %1 to label %try.cont
29+
30+
try.cont: ; preds = %entry, %catch.start
31+
ret void
32+
}
33+
34+
declare void @foo()
35+
declare i32 @__gxx_wasm_personality_v0(...)
36+
; Function Attrs: nounwind
37+
declare i8* @llvm.wasm.get.exception(token) #0
38+
; Function Attrs: nounwind
39+
declare i32 @llvm.wasm.get.ehselector(token) #0
40+
declare i8* @__cxa_begin_catch(i8*)
41+
declare void @__cxa_end_catch()
42+
; Function Attrs: returns_twice
43+
declare i32 @setjmp(%struct.__jmp_buf_tag*) #0
44+
; Function Attrs: noreturn
45+
declare void @longjmp(%struct.__jmp_buf_tag*, i32) #1
46+
declare i8* @malloc(i32)
47+
declare void @free(i8*)
48+
49+
attributes #0 = { returns_twice }
50+
attributes #1 = { noreturn }
51+
attributes #2 = { nounwind }
52+
53+
; CHECK: LLVM ERROR: When using Wasm EH with Emscripten SjLj, there is a restriction that `setjmp` function call and exception cannot be used within the same function

0 commit comments

Comments
 (0)