diff options
author | Jérôme Vouillon <jerome.vouillon@gmail.com> | 2024-04-29 13:12:44 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-29 10:12:44 -0700 |
commit | 7750570957315d21b556538375012c242d2695d6 (patch) | |
tree | da795e545632b1a8139c9a2e22da7e64f963a3ee /src/wasm/wasm-ir-builder.cpp | |
parent | 4f7c6d687e7bbf70888ba046e5ee676f0bdf5815 (diff) | |
download | binaryen-7750570957315d21b556538375012c242d2695d6.tar.gz binaryen-7750570957315d21b556538375012c242d2695d6.tar.bz2 binaryen-7750570957315d21b556538375012c242d2695d6.zip |
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.
Diffstat (limited to 'src/wasm/wasm-ir-builder.cpp')
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 11 |
1 files changed, 8 insertions, 3 deletions
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{}; } |