diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-ir-builder.h | 1 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 12 |
2 files changed, 11 insertions, 2 deletions
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index d9075952d..9b8ae043f 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -239,6 +239,7 @@ private: // The branch label name for this scope. Always fresh, never shadowed. Name label; + bool labelUsed = false; std::vector<Expression*> exprStack; // Whether we have seen an unreachable instruction and are in diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 964676ff9..dfbf156b2 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -584,10 +584,17 @@ Result<> IRBuilder::visitEnd() { CHECK_ERR(expr); // If the scope expression cannot be directly labeled, we may need to wrap it - // in a block. + // in a block. It's possible that the scope expression becomes typed + // unreachable when it is finalized, but if the wrapper block is targeted by + // any branches, the target block needs to have the original non-unreachable + // type of the scope expression. + auto originalScopeType = scope.getResultType(); auto maybeWrapForLabel = [&](Expression* curr) -> Expression* { if (scope.label) { - return builder.makeBlock(scope.label, {curr}, scope.getResultType()); + return builder.makeBlock(scope.label, + {curr}, + scope.labelUsed ? originalScopeType + : scope.getResultType()); } return curr; }; @@ -638,6 +645,7 @@ Result<Name> IRBuilder::getLabelName(Index label) { // The scope does not already have a name, so we need to create one. scopeLabel = makeFresh("label"); } + (*scope)->labelUsed = true; return scopeLabel; } |