diff options
-rw-r--r-- | src/ir/possible-contents.cpp | 8 | ||||
-rw-r--r-- | test/lit/passes/gufa-refs.wast | 29 |
2 files changed, 35 insertions, 2 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 6c6c1b97e..e991a68fd 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -1013,7 +1013,11 @@ struct InfoCollector visitArraySet(set); } void visitArrayInit(ArrayInit* curr) { - if (curr->type == Type::unreachable) { + // Check for both unreachability and a bottom type. In either case we have + // no work to do, and would error on an assertion below in finding the array + // type. + auto field = GCTypeUtils::getField(curr->ref->type); + if (!field) { return; } // See ArrayCopy, above. Here an additional complexity is that we need to @@ -1022,7 +1026,7 @@ struct InfoCollector // manually here as a fake unknown value, using a fake local.get that we // root. // TODO: be more precise about what is in the table - auto valueType = curr->ref->type.getHeapType().getArray().element.type; + auto valueType = field->type; Builder builder(*getModule()); auto* get = builder.makeLocalGet(-1, valueType); addRoot(get); diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index aac20e9fe..fe210e149 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -5613,3 +5613,32 @@ ) ) ) + +;; Test that we do not error on array.init of a bottom type. +(module + (type $[mut:i32] (array (mut i32))) + + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (data $0 "") + (data $0 "") + + ;; CHECK: (func $test (type $none_=>_none) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $test + (array.init_data $[mut:i32] $0 + (ref.as_non_null + (ref.null none) + ) + (i32.const 0) + (i32.const 0) + (i32.const 1) + ) + ) +) |