diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 23 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 30 |
2 files changed, 21 insertions, 32 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 64c7fda02..e295d3931 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -865,7 +865,16 @@ void FunctionValidator::visitIf(If* curr) { curr, "returning if-else's false must have right type"); } else { - if (curr->condition->type != Type::unreachable) { + if (curr->condition->type == Type::unreachable) { + shouldBeTrue( + curr->ifTrue->type == Type::unreachable || + curr->ifFalse->type == Type::unreachable || + (curr->ifTrue->type == Type::none && + curr->ifFalse->type == Type::none) || + Type::hasLeastUpperBound(curr->ifTrue->type, curr->ifFalse->type), + curr, + "arms of unreachable if-else must have compatible types"); + } else { shouldBeEqual(curr->ifTrue->type, Type(Type::unreachable), curr, @@ -876,18 +885,6 @@ void FunctionValidator::visitIf(If* curr) { "unreachable if-else must have unreachable false"); } } - if (curr->ifTrue->type.isConcrete()) { - shouldBeSubType(curr->ifTrue->type, - curr->type, - curr, - "if type must match concrete ifTrue"); - } - if (curr->ifFalse->type.isConcrete()) { - shouldBeSubType(curr->ifFalse->type, - curr->type, - curr, - "if type must match concrete ifFalse"); - } } } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index f89ef80c2..38f35411f 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -215,28 +215,20 @@ void Block::finalize(std::optional<Type> type_, Breakability breakability) { } void If::finalize(std::optional<Type> type_) { - if (type_) { - type = *type_; - if (type == Type::none && (condition->type == Type::unreachable || - (ifFalse && ifTrue->type == Type::unreachable && - ifFalse->type == Type::unreachable))) { - type = Type::unreachable; - } + // The If is unreachable if the condition is unreachable or both arms are + // unreachable. + if (condition->type == Type::unreachable || + (ifFalse && ifTrue->type == Type::unreachable && + ifFalse->type == Type::unreachable)) { + type = Type::unreachable; return; } - type = ifFalse ? Type::getLeastUpperBound(ifTrue->type, ifFalse->type) - : Type::none; - // if the arms return a value, leave it even if the condition - // is unreachable, we still mark ourselves as having that type, e.g. - // (if (result i32) - // (unreachable) - // (i32.const 10) - // (i32.const 20) - // ) - // otherwise, if the condition is unreachable, so is the if - if (type == Type::none && condition->type == Type::unreachable) { - type = Type::unreachable; + if (type_) { + type = *type_; + } else { + type = ifFalse ? Type::getLeastUpperBound(ifTrue->type, ifFalse->type) + : Type::none; } } |