Skip to content

Commit 991adff

Browse files
authored
[WebAssembly] Allow try_table to target loops in AsmTypeCheck (#111432)
1 parent 2ca8501 commit 991adff

File tree

4 files changed

+72
-6
lines changed

4 files changed

+72
-6
lines changed

llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmTypeCheck.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,11 +371,16 @@ bool WebAssemblyAsmTypeCheck::checkTryTable(SMLoc ErrorLoc,
371371
if (Level < BlockInfoStack.size()) {
372372
const auto &DestBlockInfo =
373373
BlockInfoStack[BlockInfoStack.size() - Level - 1];
374-
if (compareTypes(SentTypes, DestBlockInfo.Sig.Returns)) {
374+
ArrayRef<wasm::ValType> DestTypes;
375+
if (DestBlockInfo.IsLoop)
376+
DestTypes = DestBlockInfo.Sig.Params;
377+
else
378+
DestTypes = DestBlockInfo.Sig.Returns;
379+
if (compareTypes(SentTypes, DestTypes)) {
375380
std::string ErrorMsg =
376381
ErrorMsgBase + "type mismatch, catch tag type is " +
377382
getTypesString(SentTypes) + ", but destination's type is " +
378-
getTypesString(DestBlockInfo.Sig.Returns);
383+
getTypesString(DestTypes);
379384
Error |= typeError(ErrorLoc, ErrorMsg);
380385
}
381386
} else {

llvm/test/MC/WebAssembly/annotations.s

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
.section .text.test_annotation,"",@
88
.type test_annotation,@function
99
test_annotation:
10-
.functype test_annotation () -> ()
10+
.functype test_annotation (exnref) -> ()
1111
.tagtype __cpp_exception i32
1212
.tagtype __c_longjmp i32
1313
try
@@ -54,8 +54,18 @@ test_annotation:
5454
return
5555
end_block
5656
drop
57-
end_function
5857

58+
i32.const 0
59+
loop (i32) -> ()
60+
local.get 0
61+
loop (exnref) -> ()
62+
try_table (catch __cpp_exception 1) (catch_all_ref 0)
63+
end_try_table
64+
drop
65+
end_loop
66+
drop
67+
end_loop
68+
end_function
5969

6070
# CHECK: test_annotation:
6171
# CHECK: try
@@ -105,5 +115,16 @@ test_annotation:
105115
# CHECK-NEXT: return
106116
# CHECK-NEXT: end_block # label7:
107117
# CHECK-NEXT: drop
108-
# CHECK-NEXT: end_function
109118

119+
# CHECK: i32.const 0
120+
# CHECK-NEXT: loop (i32) -> () # label12:
121+
# CHECK-NEXT: local.get 0
122+
# CHECK-NEXT: loop (exnref) -> () # label13:
123+
# CHECK-NEXT: try_table (catch __cpp_exception 1) (catch_all_ref 0) # 1: up to label12
124+
# CHECK-NEXT: # 0: up to label13
125+
# CHECK-NEXT: end_try_table # label14:
126+
# CHECK-NEXT: drop
127+
# CHECK-NEXT: end_loop
128+
# CHECK-NEXT: drop
129+
# CHECK-NEXT: end_loop
130+
# CHECK-NEXT: end_function

llvm/test/MC/WebAssembly/eh-assembly.s

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
.functype foo () -> ()
88

99
eh_test:
10-
.functype eh_test () -> ()
10+
.functype eh_test (exnref) -> ()
1111

1212
# try_table with all four kinds of catch clauses
1313
block exnref
@@ -82,6 +82,18 @@ eh_test:
8282
end_try_table
8383
drop
8484
drop
85+
86+
# try_table targeting loops
87+
i32.const 0
88+
loop (i32) -> ()
89+
local.get 0
90+
loop (exnref) -> ()
91+
try_table (catch __cpp_exception 1) (catch_all_ref 0)
92+
end_try_table
93+
drop
94+
end_loop
95+
drop
96+
end_loop
8597
end_function
8698

8799
eh_legacy_test:
@@ -203,6 +215,17 @@ eh_legacy_test:
203215
# CHECK-NEXT: drop
204216
# CHECK-NEXT: drop
205217

218+
# CHECK: i32.const 0
219+
# CHECK-NEXT: loop (i32) -> ()
220+
# CHECK-NEXT: local.get 0
221+
# CHECK-NEXT: loop (exnref) -> ()
222+
# CHECK-NEXT: try_table (catch __cpp_exception 1) (catch_all_ref 0)
223+
# CHECK: end_try_table
224+
# CHECK-NEXT: drop
225+
# CHECK-NEXT: end_loop
226+
# CHECK-NEXT: drop
227+
# CHECK-NEXT: end_loop
228+
206229
# CHECK: eh_legacy_test:
207230
# CHECK: try
208231
# CHECK-NEXT: i32.const 3

llvm/test/MC/WebAssembly/type-checker-errors.s

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -966,4 +966,21 @@ eh_test:
966966
end_block
967967
end_block
968968
drop
969+
970+
loop
971+
i32.const 0
972+
loop (i32) -> ()
973+
loop (i32) -> ()
974+
loop
975+
# CHECK: :[[@LINE+4]]:11: error: try_table: catch index 0: type mismatch, catch tag type is [i32], but destination's type is []
976+
# CHECK: :[[@LINE+3]]:11: error: try_table: catch index 1: type mismatch, catch tag type is [i32, exnref], but destination's type is [i32]
977+
# CHECK: :[[@LINE+2]]:11: error: try_table: catch index 2: type mismatch, catch tag type is [], but destination's type is [i32]
978+
# CHECK: :[[@LINE+1]]:11: error: try_table: catch index 3: type mismatch, catch tag type is [exnref], but destination's type is []
979+
try_table (catch __cpp_exception 0) (catch_ref __cpp_exception 1) (catch_all 2) (catch_all_ref 3)
980+
end_try_table
981+
end_loop
982+
drop
983+
end_loop
984+
end_loop
985+
end_loop
969986
end_function

0 commit comments

Comments
 (0)