Skip to content

Commit

Permalink
Properly validate ref.cast when lacking a common supertype (#6741)
Browse files Browse the repository at this point in the history

When lacking a common supertype the GLB operation makes the type of the cast
unreachable, which errors on getHeapType in the later code.

Fixes #6738
  • Loading branch information
kripken committed Jul 23, 2024
1 parent 538c528 commit 353e19e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2780,6 +2780,21 @@ void FunctionValidator::visitRefCast(RefCast* curr) {
curr->ref->type.isRef(), curr, "ref.cast ref must have ref type")) {
return;
}
// If the cast is unreachable but not the ref (we ruled out the former
// earlier), then the cast is unreachable because the cast type had no
// common supertype with the ref, which is invalid. This is the same as the
// check below us, but we must do it first (as getHeapType fails otherwise).
if (!shouldBeUnequal(
curr->type,
Type(Type::unreachable),
curr,
"ref.cast target type and ref type must have a common supertype")) {
return;
}
// Also error (more generically) on i32 and anything else invalid here.
if (!shouldBeTrue(curr->type.isRef(), curr, "ref.cast must have ref type")) {
return;
}
shouldBeEqual(
curr->type.getHeapType().getBottom(),
curr->ref->type.getHeapType().getBottom(),
Expand Down
10 changes: 10 additions & 0 deletions test/spec/ref_cast.wast
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@
"common supertype"
)

(assert_invalid
(module
(type $t0 (struct))
(func (export "test-ref-cast-extern") (result anyref)
(ref.cast (ref extern) (struct.new $t0))
)
)
"common supertype"
)

(assert_malformed
(module quote "(func (ref.cast i32 (unreachable)))")
"expected reftype"
Expand Down

0 comments on commit 353e19e

Please sign in to comment.