diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -322,7 +322,9 @@ } } - void push(NestingType NT) { NestingStack.push_back({NT, wasm::WasmSignature()}); } + void push(NestingType NT, wasm::WasmSignature Sig = wasm::WasmSignature()) { + NestingStack.push_back({NT, Sig}); + } bool pop(StringRef Ins, NestingType NT1, NestingType NT2 = Undefined) { if (NestingStack.empty()) @@ -336,6 +338,19 @@ return false; } + // Pop a NestingType and push a new NestingType with the same signature. Used + // for if-else and try-catch(_all). + bool popAndPushWithSameSignature(StringRef Ins, NestingType PopNT, + NestingType PushNT) { + if (NestingStack.empty()) + return error(Twine("End of block construct with no start: ") + Ins); + auto Sig = NestingStack.back().Sig; + if (pop(Ins, PopNT)) + return true; + push(PushNT, Sig); + return false; + } + bool ensureEmptyNestingStack(SMLoc Loc = SMLoc()) { auto Err = !NestingStack.empty(); while (!NestingStack.empty()) { @@ -587,17 +602,14 @@ push(If); ExpectBlockType = true; } else if (Name == "else") { - if (pop(Name, If)) + if (popAndPushWithSameSignature(Name, If, Else)) return true; - push(Else); } else if (Name == "catch") { - if (pop(Name, Try)) + if (popAndPushWithSameSignature(Name, Try, Try)) return true; - push(Try); } else if (Name == "catch_all") { - if (pop(Name, Try)) + if (popAndPushWithSameSignature(Name, Try, CatchAll)) return true; - push(CatchAll); } else if (Name == "end_if") { if (pop(Name, If, Else)) return true; diff --git a/llvm/test/MC/WebAssembly/type-checker-errors.s b/llvm/test/MC/WebAssembly/type-checker-errors.s --- a/llvm/test/MC/WebAssembly/type-checker-errors.s +++ b/llvm/test/MC/WebAssembly/type-checker-errors.s @@ -281,7 +281,7 @@ if i32 i32.const 2 else -# FIXME: Should complain about insufficient values on the stack. +# CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack end_if drop end_function @@ -292,8 +292,8 @@ if i32 i32.const 2 else -# FIXME: Should complain about a type mismatch. f32.const 3.0 +# CHECK: :[[@LINE+1]]:3: error: end got f32, expected i32 end_if drop end_function @@ -322,20 +322,26 @@ end_function .tagtype tag_i32 i32 +.tagtype tag_f32 f32 end_try_insufficient_values_on_stack: .functype end_try_insufficient_values_on_stack () -> () try i32 + i32.const 0 + catch_all # CHECK: :[[@LINE+1]]:3: error: end: insufficient values on the type stack end_try + drop end_function end_try_type_mismatch: .functype end_try_type_mismatch () -> () try i32 - f32.const 1.0 + i32.const 0 + catch tag_f32 # CHECK: :[[@LINE+1]]:3: error: end got f32, expected i32 end_try + drop end_function catch_insufficient_values_on_stack: