[WebAssembly] Fix typechecking for else MCInst

When hitting an else clause the type Stack should be reset to as it was at the start of the if, without taking into account the Type inserted into the Stack during the then branch of the if.

Reviewed By: aardappel

Differential Revision: https://reviews.llvm.org/D115748
This commit is contained in:
Paulo Matos 2021-12-16 10:45:48 +01:00
parent 6734be290b
commit c92d45913c
3 changed files with 33 additions and 3 deletions

View File

@ -112,9 +112,18 @@ bool WebAssemblyAsmTypeCheck::getLocal(SMLoc ErrorLoc, const MCInst &Inst,
return false;
}
bool WebAssemblyAsmTypeCheck::checkEnd(SMLoc ErrorLoc) {
bool WebAssemblyAsmTypeCheck::checkEnd(SMLoc ErrorLoc, bool PopVals) {
if (LastSig.Returns.size() > Stack.size())
return typeError(ErrorLoc, "end: insufficient values on the type stack");
if (PopVals) {
for (auto VT : llvm::reverse(LastSig.Returns)) {
if (popType(ErrorLoc, VT))
return true;
}
return false;
}
for (size_t i = 0; i < LastSig.Returns.size(); i++) {
auto EVT = LastSig.Returns[i];
auto PVT = Stack[Stack.size() - LastSig.Returns.size() + i];
@ -221,7 +230,7 @@ bool WebAssemblyAsmTypeCheck::typeCheck(SMLoc ErrorLoc, const MCInst &Inst) {
return true;
} else if (Name == "end_block" || Name == "end_loop" || Name == "end_if" ||
Name == "else" || Name == "end_try") {
if (checkEnd(ErrorLoc))
if (checkEnd(ErrorLoc, Name == "else"))
return true;
if (Name == "end_block")
Unreachable = false;

View File

@ -39,7 +39,7 @@ class WebAssemblyAsmTypeCheck final {
bool typeError(SMLoc ErrorLoc, const Twine &Msg);
bool popType(SMLoc ErrorLoc, Optional<wasm::ValType> EVT);
bool getLocal(SMLoc ErrorLoc, const MCInst &Inst, wasm::ValType &Type);
bool checkEnd(SMLoc ErrorLoc);
bool checkEnd(SMLoc ErrorLoc, bool PopVals = false);
bool checkSig(SMLoc ErrorLoc, const wasm::WasmSignature &Sig);
bool getSymRef(SMLoc ErrorLoc, const MCInst &Inst,
const MCSymbolRefExpr *&SymRef);

View File

@ -0,0 +1,21 @@
# Check that it converts to .o without errors
# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+reference-types < %s
objects:
.tabletype objects,externref
handle_value:
.hidden handle_value
.globl handle_value
.type handle_value,@function
.functype handle_value (i32) -> (externref)
local.get 0
i32.const -1
i32.eq
if externref
ref.null_extern
else
local.get 0
table.get objects
end_if
end_function