Skip to content

Commit 86c65fc

Browse files
committed
[WebAssembly] Correctly check end_if/end_try with else/catch
When we encounter an `else`, `catch`, or `catch_all`, we currently just push the structure `NestingType` and don't preserve the original `if` and `try`'s signature. So after we pass `else`/`catch`/`catch_all`, we can't check if the values on stack have the correct types when we encounter `end_if` or `end_try`. This CL fixes the issue, and modifies the existing test to be correct (some of them had `try` without `catch`). Reviewed By: dschuff Differential Revision: https://reviews.llvm.org/D147881
1 parent 3e9881b commit 86c65fc

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

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

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,9 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
322322
}
323323
}
324324

325-
void push(NestingType NT) { NestingStack.push_back({NT, wasm::WasmSignature()}); }
325+
void push(NestingType NT, wasm::WasmSignature Sig = wasm::WasmSignature()) {
326+
NestingStack.push_back({NT, Sig});
327+
}
326328

327329
bool pop(StringRef Ins, NestingType NT1, NestingType NT2 = Undefined) {
328330
if (NestingStack.empty())
@@ -336,6 +338,19 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
336338
return false;
337339
}
338340

341+
// Pop a NestingType and push a new NestingType with the same signature. Used
342+
// for if-else and try-catch(_all).
343+
bool popAndPushWithSameSignature(StringRef Ins, NestingType PopNT,
344+
NestingType PushNT) {
345+
if (NestingStack.empty())
346+
return error(Twine("End of block construct with no start: ") + Ins);
347+
auto Sig = NestingStack.back().Sig;
348+
if (pop(Ins, PopNT))
349+
return true;
350+
push(PushNT, Sig);
351+
return false;
352+
}
353+
339354
bool ensureEmptyNestingStack(SMLoc Loc = SMLoc()) {
340355
auto Err = !NestingStack.empty();
341356
while (!NestingStack.empty()) {
@@ -587,17 +602,14 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
587602
push(If);
588603
ExpectBlockType = true;
589604
} else if (Name == "else") {
590-
if (pop(Name, If))
605+
if (popAndPushWithSameSignature(Name, If, Else))
591606
return true;
592-
push(Else);
593607
} else if (Name == "catch") {
594-
if (pop(Name, Try))
608+
if (popAndPushWithSameSignature(Name, Try, Try))
595609
return true;
596-
push(Try);
597610
} else if (Name == "catch_all") {
598-
if (pop(Name, Try))
611+
if (popAndPushWithSameSignature(Name, Try, CatchAll))
599612
return true;
600-
push(CatchAll);
601613
} else if (Name == "end_if") {
602614
if (pop(Name, If, Else))
603615
return true;

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ end_if_insufficient_values_on_stack_2:
281281
if i32
282282
i32.const 2
283283
else
284-
# FIXME: Should complain about insufficient values on the stack.
284+
# CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack
285285
end_if
286286
drop
287287
end_function
@@ -292,8 +292,8 @@ end_if_type_mismatch_2:
292292
if i32
293293
i32.const 2
294294
else
295-
# FIXME: Should complain about a type mismatch.
296295
f32.const 3.0
296+
# CHECK: :[[@LINE+1]]:3: error: end got f32, expected i32
297297
end_if
298298
drop
299299
end_function
@@ -322,20 +322,26 @@ else_type_mismatch:
322322
end_function
323323

324324
.tagtype tag_i32 i32
325+
.tagtype tag_f32 f32
325326

326327
end_try_insufficient_values_on_stack:
327328
.functype end_try_insufficient_values_on_stack () -> ()
328329
try i32
330+
i32.const 0
331+
catch_all
329332
# CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack
330333
end_try
334+
drop
331335
end_function
332336

333337
end_try_type_mismatch:
334338
.functype end_try_type_mismatch () -> ()
335339
try i32
336-
f32.const 1.0
340+
i32.const 0
341+
catch tag_f32
337342
# CHECK: :[[@LINE+1]]:3: error: end got f32, expected i32
338343
end_try
344+
drop
339345
end_function
340346

341347
catch_insufficient_values_on_stack:

0 commit comments

Comments
 (0)