[llvm] 90073e8 - [WebAssembly] Error out on invalid personality functions

Heejin Ahn via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 8 17:02:00 PDT 2023


Author: Heejin Ahn
Date: 2023-06-08T16:59:49-07:00
New Revision: 90073e8de3871776c4df1da78d19019990241f4d

URL: https://github.com/llvm/llvm-project/commit/90073e8de3871776c4df1da78d19019990241f4d
DIFF: https://github.com/llvm/llvm-project/commit/90073e8de3871776c4df1da78d19019990241f4d.diff

LOG: [WebAssembly] Error out on invalid personality functions

Without explicitly checking and erroring out, an invalid personality
function, which is not `__gxx_wasm_personality_v0`, caused
a segmentation fault down the line because `WasmEHFuncInfo` was not
created. This explicitly checks the validity of personality functions in
functions with EH pads and errors out explicitly with a helpful error
message. This also adds some more assertions to ensure `WasmEHFuncInfo`
is correctly created and non-null.

Invalid personality functions wouldn't be generated by our Clang, but
can be present in handwritten ll files, and more often, in files
transformed by passes like `metarenamer`, which is often used with
`bugpoint` to simplify names in `bugpoint`-reduced files.

Reviewed By: dschuff

Differential Revision: https://reviews.llvm.org/D152203

Added: 
    llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll

Modified: 
    llvm/lib/CodeGen/WasmEHPrepare.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
    llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/WasmEHPrepare.cpp b/llvm/lib/CodeGen/WasmEHPrepare.cpp
index 361f185243b1d..cc04807e84550 100644
--- a/llvm/lib/CodeGen/WasmEHPrepare.cpp
+++ b/llvm/lib/CodeGen/WasmEHPrepare.cpp
@@ -80,6 +80,7 @@
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/WasmEHFuncInfo.h"
+#include "llvm/IR/EHPersonalities.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/IntrinsicsWebAssembly.h"
 #include "llvm/InitializePasses.h"
@@ -209,6 +210,12 @@ bool WasmEHPrepare::prepareEHPads(Function &F) {
   if (CatchPads.empty() && CleanupPads.empty())
     return false;
 
+  if (!F.hasPersonalityFn() ||
+      !isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) {
+    report_fatal_error("Function '" + F.getName() +
+                       "' does not have a correct Wasm personality function "
+                       "'__gxx_wasm_personality_v0'");
+  }
   assert(F.hasPersonalityFn() && "Personality function not found");
 
   // __wasm_lpad_context global variable.

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index 70c187af73a5b..cc8052352b383 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -1291,6 +1291,7 @@ bool WebAssemblyCFGStackify::fixCatchUnwindMismatches(MachineFunction &MF) {
   // end_try
 
   const auto *EHInfo = MF.getWasmEHFuncInfo();
+  assert(EHInfo);
   SmallVector<const MachineBasicBlock *, 8> EHPadStack;
   // For EH pads that have catch unwind mismatches, a map of <EH pad, its
   // correct unwind destination>.

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
index 7e63b6b976321..ab3512cfd6408 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyExceptionInfo.cpp
@@ -121,6 +121,7 @@ void WebAssemblyExceptionInfo::recalculate(
   // and A's unwind destination is B and B's is C. When we visit B before A, we
   // end up extracting C only out of B but not out of A.
   const auto *EHInfo = MF.getWasmEHFuncInfo();
+  assert(EHInfo);
   SmallVector<std::pair<WebAssemblyException *, WebAssemblyException *>>
       UnwindWEVec;
   for (auto *DomNode : depth_first(&MDT)) {

diff  --git a/llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll b/llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll
new file mode 100644
index 0000000000000..1a4e888a26ef5
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/wasm-eh-invalid-personality.ll
@@ -0,0 +1,26 @@
+; RUN: not --crash llc < %s -wasm-enable-eh -exception-model=wasm -mattr=+exception-handling 2>&1 | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+; Tests if the compiler correctly errors out when a function having EH pads does
+; not have a correct Wasm personality function.
+
+define void @test() personality ptr @invalid_personality {
+; CHECK: LLVM ERROR: Function 'test' does not have a correct Wasm personality function '__gxx_wasm_personality_v0'
+entry:
+  invoke void @foo()
+          to label %try.cont unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %0 = catchswitch within none [label %catch.start] unwind to caller
+
+catch.start:                                      ; preds = %catch.dispatch
+  %1 = catchpad within %0 [ptr null]
+  catchret from %1 to label %try.cont
+
+try.cont:                                         ; preds = %catch, %entry
+  ret void
+}
+
+declare void @foo()
+declare i32 @invalid_personality(...)


        


More information about the llvm-commits mailing list