Skip to content

Commit a255c1e

Browse files
dschuffc-rhodes
authored andcommitted
[WebAssembly] Avoid crash in LateEHPrepare with empty cleanup pads (llvm#200322)
WebAssemblyLateEHPrepare::addCatchRefsAndThrowRefs was using Catch->getIterator()->getNextNode() to find the insertion position after the CATCH (or CATCH_ALL) instruction in an EH pad. If the CATCH/CATCH_ALL instruction is the last instruction in the basic block, getNextNode() returns nullptr, which causees a crash when passed to BuildMI. This patch fixes it by using std::next(Catch->getIterator()) which returns MBB.end() if the catch is the last instruction, and the overload of BuildMI that takes an iterator correctly handles BB.end(). Fixes llvm#197077 Assisted-By: Gemini (cherry picked from commit dc40fcc)
1 parent a2b7790 commit a255c1e

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,8 @@ bool WebAssemblyLateEHPrepare::addCatchRefsAndThrowRefs(MachineFunction &MF) {
312312
// caught exception is rethrown. And convert RETHROWs to THROW_REFs.
313313
for (auto &[EHPad, Rethrows] : EHPadToRethrows) {
314314
auto *Catch = WebAssembly::findCatch(EHPad);
315-
auto *InsertPos = Catch->getIterator()->getNextNode();
315+
assert(Catch && "CATCH not found in EHPad");
316+
auto InsertPos = std::next(Catch->getIterator());
316317
auto ExnReg = MRI.createVirtualRegister(&WebAssembly::EXNREFRegClass);
317318
if (Catch->getOpcode() == WebAssembly::CATCH) {
318319
MachineInstrBuilder MIB = BuildMI(*EHPad, InsertPos, Catch->getDebugLoc(),

llvm/test/CodeGen/WebAssembly/exception.ll

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,5 +672,32 @@ attributes #0 = { nounwind }
672672
attributes #1 = { noreturn }
673673
attributes #2 = { noreturn nounwind }
674674

675+
; CHECK-LABEL: empty_cleanup_pad:
676+
; CHECK: try_table (catch_all_ref 0)
677+
; CHECK: throw_ref
678+
define void @empty_cleanup_pad(i32 %arg) personality ptr @__gxx_wasm_personality_v0 {
679+
entry:
680+
br label %loop
681+
682+
loop:
683+
invoke void @foo()
684+
to label %loop unwind label %cleanup
685+
686+
cleanup:
687+
%exn = cleanuppad within none []
688+
br label %dispatch
689+
690+
dispatch: ; preds = %cleanup, %dispatch
691+
%cond = icmp eq i32 %arg, 0
692+
br i1 %cond, label %ret, label %dispatch
693+
694+
ret: ; preds = %dispatch
695+
cleanupret from %exn unwind label %cleanup2
696+
697+
cleanup2: ; preds = %ret
698+
%exn2 = cleanuppad within none []
699+
ret void
700+
}
701+
675702
;; The exception tag should not be defined locally
676703
; CHECK-NOT: __cpp_exception:

0 commit comments

Comments
 (0)