diff options
author | Alon Zakai <azakai@google.com> | 2024-07-24 13:54:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-24 13:54:13 -0700 |
commit | 017b473f05b8dde4da8aadd154e6d2606071d2cb (patch) | |
tree | dd4bf67b0d12d371aaf2fcae62b197948f5fcba1 | |
parent | 353e19e3343fb06eacdd8b438b305b536291bdd5 (diff) | |
download | binaryen-017b473f05b8dde4da8aadd154e6d2606071d2cb.tar.gz binaryen-017b473f05b8dde4da8aadd154e6d2606071d2cb.tar.bz2 binaryen-017b473f05b8dde4da8aadd154e6d2606071d2cb.zip |
Validate RefAsNonNull (#6785)
Fixes #6781
-rw-r--r-- | src/wasm/wasm-validator.cpp | 13 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 8 | ||||
-rw-r--r-- | test/lit/validation/non-ref.wast | 13 |
3 files changed, 31 insertions, 3 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index 3abb106b3..ce7d0df3c 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2230,10 +2230,19 @@ void FunctionValidator::visitRefIsNull(RefIsNull* curr) { } void FunctionValidator::visitRefAs(RefAs* curr) { + if (curr->value->type != Type::unreachable && + !shouldBeTrue( + curr->value->type.isRef(), curr, "ref.as value must be reference")) { + return; + } switch (curr->op) { - default: - // TODO: validate all the other ref.as_* + case RefAsNonNull: { + shouldBeTrue( + getModule()->features.hasReferenceTypes(), + curr, + "ref.as requires reference-types [--enable-reference-types]"); break; + } case AnyConvertExtern: { shouldBeTrue(getModule()->features.hasGC(), curr, diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 4c30a4e32..b17250e6c 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1223,7 +1223,13 @@ void ArrayInitElem::finalize() { } void RefAs::finalize() { - if (value->type == Type::unreachable) { + // An unreachable child means we are unreachable. Also set ourselves to + // unreachable when the child is invalid (say, it is an i32 or some other non- + // reference), which avoids getHeapType() erroring right after us (in this + // situation, the validator will report an error later). + // TODO: Remove that part when we solve the validation issue more generally, + // see https://github.com/WebAssembly/binaryen/issues/6781 + if (!value->type.isRef()) { type = Type::unreachable; return; } diff --git a/test/lit/validation/non-ref.wast b/test/lit/validation/non-ref.wast new file mode 100644 index 000000000..a065b6723 --- /dev/null +++ b/test/lit/validation/non-ref.wast @@ -0,0 +1,13 @@ +;; RUN: not wasm-opt %s -all 2>&1 | filecheck %s + +;; CHECK: ref.as value must be reference + +(module + (func $test + (drop + (ref.as_non_null + (i32.const 42) + ) + ) + ) +) |