diff options
-rw-r--r-- | src/ir/subtypes.h | 13 | ||||
-rw-r--r-- | test/lit/passes/signature-refining.wast | 20 |
2 files changed, 30 insertions, 3 deletions
diff --git a/src/ir/subtypes.h b/src/ir/subtypes.h index 420bdcc1d..2a629a05d 100644 --- a/src/ir/subtypes.h +++ b/src/ir/subtypes.h @@ -37,14 +37,21 @@ struct SubTypes { SubTypes(Module& wasm) : SubTypes(ModuleUtils::collectHeapTypes(wasm)) {} const std::vector<HeapType>& getStrictSubTypes(HeapType type) const { + // When we return an empty result, use a canonical constant empty vec to + // avoid allocation. + static const std::vector<HeapType> empty; + + if (type.isBottom()) { + // Bottom types have no subtypes. + return empty; + } + assert(!type.isBasic()); if (auto iter = typeSubTypes.find(type); iter != typeSubTypes.end()) { return iter->second; } - // No entry exists. Return a canonical constant empty vec, to avoid - // allocation. - static const std::vector<HeapType> empty; + // No entry exists. return empty; } diff --git a/test/lit/passes/signature-refining.wast b/test/lit/passes/signature-refining.wast index dea74451a..11bc84f35 100644 --- a/test/lit/passes/signature-refining.wast +++ b/test/lit/passes/signature-refining.wast @@ -830,3 +830,23 @@ ) ) ) + +(module + ;; CHECK: (type $F (func)) + (type $F (func)) + + ;; CHECK: (func $func (type $F) + ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null nofunc) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $func + ;; We should not error on a call_ref to a bottom type. + (call_ref $F + (ref.null nofunc) + ) + ) +) |