diff options
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 10 | ||||
-rw-r--r-- | test/spec/shared-array.wast | 12 |
2 files changed, 21 insertions, 1 deletions
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 2f2f3b595..b238a926c 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1801,6 +1801,16 @@ Result<> IRBuilder::makeArrayInitData(HeapType type, Name data) { } Result<> IRBuilder::makeArrayInitElem(HeapType type, Name elem) { + // Validate the elem type, too, before we potentially forget the type + // annotation. + if (!type.isArray()) { + return Err{"expected array type annotation on array.init_elem"}; + } + if (!Type::isSubType(wasm.getElementSegment(elem)->type, + type.getArray().element.type)) { + return Err{"element segment type must be a subtype of array element type " + "on array.init_elem"}; + } ArrayInitElem curr; CHECK_ERR(ChildPopper{*this}.visitArrayInitElem(&curr, type)); CHECK_ERR(validateTypeAnnotation(type, curr.ref)); diff --git a/test/spec/shared-array.wast b/test/spec/shared-array.wast index 8c748fd20..f06fad2a7 100644 --- a/test/spec/shared-array.wast +++ b/test/spec/shared-array.wast @@ -122,7 +122,7 @@ (type $funcs (shared (array (mut (ref null (shared func)))))) (data) - (elem (ref null (shared any))) + (elem (ref null (shared func))) (func (array.get_s $i8 (ref.null (shared none)) (i32.const 0)) (drop)) (func (array.get_u $i8 (ref.null (shared none)) (i32.const 0)) (drop)) @@ -137,3 +137,13 @@ (func (array.init_data $i8 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) (func (array.init_elem $funcs 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) ) + +;; Check validation of element segments +(assert_invalid + (module + (type $array (shared (array (mut (ref null (shared any)))))) + (elem (ref null (shared func))) + (func (array.init_elem $array 0 (ref.null (shared none)) (i32.const 0) (i32.const 0) (i32.const 0))) + ) + "invalid field type" +) |