diff options
author | Alon Zakai <azakai@google.com> | 2022-11-16 12:09:06 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-16 12:09:06 -0800 |
commit | 3528a593f5a588d1819c6de9645b63361c13bf6b (patch) | |
tree | 4e242ba97db33272b5917c2bcc9a10686ebe0625 | |
parent | 41a2f9f394c9bb526c7a3184e571360e3813fb50 (diff) | |
download | binaryen-3528a593f5a588d1819c6de9645b63361c13bf6b.tar.gz binaryen-3528a593f5a588d1819c6de9645b63361c13bf6b.tar.bz2 binaryen-3528a593f5a588d1819c6de9645b63361c13bf6b.zip |
[Wasm GC] Fix a GUFA bug on null call_ref targets (#5262)
If the target is a bottom type then it is a heap type but it is not a signature
type, and we should treat it as unreachable (and not crash).
-rw-r--r-- | src/ir/possible-contents.cpp | 6 | ||||
-rw-r--r-- | test/lit/passes/gufa-refs.wast | 24 |
2 files changed, 28 insertions, 2 deletions
diff --git a/src/ir/possible-contents.cpp b/src/ir/possible-contents.cpp index 5170d8fa3..0284101ed 100644 --- a/src/ir/possible-contents.cpp +++ b/src/ir/possible-contents.cpp @@ -763,6 +763,12 @@ struct InfoCollector }); } template<typename T> void handleIndirectCall(T* curr, HeapType targetType) { + // If the heap type is not a signature, which is the case for a bottom type + // (null) then nothing can be called. + if (!targetType.isSignature()) { + assert(targetType.isBottom()); + return; + } handleCall( curr, [&](Index i) { diff --git a/test/lit/passes/gufa-refs.wast b/test/lit/passes/gufa-refs.wast index a27e07f5f..310bef59b 100644 --- a/test/lit/passes/gufa-refs.wast +++ b/test/lit/passes/gufa-refs.wast @@ -4504,10 +4504,10 @@ ;; CHECK: (type $i2 (func_subtype (param i32) func)) (type $i2 (func (param i32))) - ;; CHECK: (type $none_=>_i32 (func_subtype (result i32) func)) - ;; CHECK: (type $none_=>_none (func_subtype func)) + ;; CHECK: (type $none_=>_i32 (func_subtype (result i32) func)) + ;; CHECK: (import "a" "b" (func $import (result i32))) (import "a" "b" (func $import (result i32))) @@ -4609,6 +4609,26 @@ (ref.func $reffed2) ) ) + + ;; CHECK: (func $call_ref-nofunc (type $none_=>_none) + ;; CHECK-NEXT: (block ;; (replaces something unreachable we can't emit) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (ref.null nofunc) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (unreachable) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $call_ref-nofunc + ;; Test a call_ref of something of type nofunc. That has a heap type, but it + ;; is not a signature type. We should not crash on that. + (call_ref $i1 + (i32.const 1) + (ref.null nofunc) + ) + ) ) ;; Limited cone reads. |