[llvm] 86c65fc - [WebAssembly] Correctly check end_if/end_try with else/catch

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 11 02:07:59 PDT 2023


Author: Heejin Ahn
Date: 2023-04-11T02:07:45-07:00
New Revision: 86c65fc4aa783071925e92340585456d7580dbf6

URL: https://github.com/llvm/llvm-project/commit/86c65fc4aa783071925e92340585456d7580dbf6
DIFF: https://github.com/llvm/llvm-project/commit/86c65fc4aa783071925e92340585456d7580dbf6.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
    llvm/test/MC/WebAssembly/type-checker-errors.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index eeffc5ac2c69..0e2072f8568a 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -322,7 +322,9 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
     }
   }
 
-  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 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
     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 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
       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
index a7d6823bc00a..87f88c87967c 100644
--- a/llvm/test/MC/WebAssembly/type-checker-errors.s
+++ b/llvm/test/MC/WebAssembly/type-checker-errors.s
@@ -281,7 +281,7 @@ end_if_insufficient_values_on_stack_2:
   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 @@ end_if_type_mismatch_2:
   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 @@ else_type_mismatch:
   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:


        


More information about the llvm-commits mailing list