From 7750570957315d21b556538375012c242d2695d6 Mon Sep 17 00:00:00 2001 From: Jérôme Vouillon Date: Mon, 29 Apr 2024 13:12:44 -0400 Subject: Fix a bug with unreachable control flow in IRBuilder (#6558) When branches target control flow structures other than blocks or loops, the IRBuilder wraps those control flow structures with an extra block for the branches to target in Binaryen IR. When the control flow structure is unreachable because all its bodies are unreachable, the wrapper block may still need to have a non-unreachable type if it is targeted by branches. This is achieved by tracking whether the wrapper block will be targeted by any branches and use the control flow structure's original, non-unreachable type if so. However, this was not properly tracked when moving into the `else` branch of an `if` or the `catch`/`cath_all` handlers of a `try` block. --- src/wasm/wasm-ir-builder.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/wasm/wasm-ir-builder.cpp') diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index ccd2ee77a..6322a5786 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -810,10 +810,11 @@ Result<> IRBuilder::visitElse() { } auto originalLabel = scope.getOriginalLabel(); auto label = scope.label; + auto labelUsed = scope.labelUsed; auto expr = finishScope(); CHECK_ERR(expr); iff->ifTrue = *expr; - pushScope(ScopeCtx::makeElse(iff, originalLabel, label)); + pushScope(ScopeCtx::makeElse(iff, originalLabel, label, labelUsed)); return Ok{}; } @@ -830,6 +831,7 @@ Result<> IRBuilder::visitCatch(Name tag) { } auto originalLabel = scope.getOriginalLabel(); auto label = scope.label; + auto labelUsed = scope.labelUsed; auto branchLabel = scope.branchLabel; auto expr = finishScope(); CHECK_ERR(expr); @@ -839,7 +841,8 @@ Result<> IRBuilder::visitCatch(Name tag) { tryy->catchBodies.push_back(*expr); } tryy->catchTags.push_back(tag); - pushScope(ScopeCtx::makeCatch(tryy, originalLabel, label, branchLabel)); + pushScope( + ScopeCtx::makeCatch(tryy, originalLabel, label, labelUsed, branchLabel)); // Push a pop for the exception payload. auto params = wasm.getTag(tag)->sig.params; if (params != Type::none) { @@ -861,6 +864,7 @@ Result<> IRBuilder::visitCatchAll() { } auto originalLabel = scope.getOriginalLabel(); auto label = scope.label; + auto labelUsed = scope.labelUsed; auto branchLabel = scope.branchLabel; auto expr = finishScope(); CHECK_ERR(expr); @@ -869,7 +873,8 @@ Result<> IRBuilder::visitCatchAll() { } else { tryy->catchBodies.push_back(*expr); } - pushScope(ScopeCtx::makeCatchAll(tryy, originalLabel, label, branchLabel)); + pushScope( + ScopeCtx::makeCatchAll(tryy, originalLabel, label, labelUsed, branchLabel)); return Ok{}; } -- cgit v1.2.3