diff --git a/src/wasm-type.h b/src/wasm-type.h index 591b2312f82..8361c9049c3 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -907,6 +907,8 @@ struct TypeBuilder { InvalidFuncType, // A shared type with shared-everything disabled. InvalidSharedType, + // WaitQueue was used with shared-everything disabled. + InvalidWaitQueue, // A string type with strings disabled. InvalidStringType, // A non-shared field of a shared heap type. diff --git a/src/wasm/wasm-type.cpp b/src/wasm/wasm-type.cpp index 010ff505fde..ab5275c4944 100644 --- a/src/wasm/wasm-type.cpp +++ b/src/wasm/wasm-type.cpp @@ -1447,6 +1447,8 @@ std::ostream& operator<<(std::ostream& os, TypeBuilder::ErrorReason reason) { return os << "Continuation has invalid function type"; case TypeBuilder::ErrorReason::InvalidSharedType: return os << "Shared types require shared-everything"; + case TypeBuilder::ErrorReason::InvalidWaitQueue: + return os << "Waitqueues require shared-everything"; case TypeBuilder::ErrorReason::InvalidStringType: return os << "String types require strings feature"; case TypeBuilder::ErrorReason::InvalidUnsharedField: @@ -2455,6 +2457,10 @@ validateStruct(const Struct& struct_, FeatureSet feats, bool isShared) { if (auto err = validateType(field.type, feats, isShared)) { return err; } + if (field.packedType == Field::PackedType::WaitQueue && + !feats.hasSharedEverything()) { + return TypeBuilder::ErrorReason::InvalidWaitQueue; + } } return std::nullopt; } diff --git a/test/lit/validation/waitqueue.wast b/test/lit/validation/waitqueue.wast new file mode 100644 index 00000000000..adf01d961a6 --- /dev/null +++ b/test/lit/validation/waitqueue.wast @@ -0,0 +1,9 @@ +;; RUN: not wasm-opt --enable-reference-types --enable-gc %s 2>&1 | filecheck %s + +(module + ;; CHECK: invalid type: Waitqueues require shared-everything + (type $t (struct (field waitqueue))) + + ;; use $t so wasm-opt doesn't drop the definition + (global (ref null $t) (ref.null $t)) +)