diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc index 7551a7a558..62d92a16b7 100644 --- a/src/reader/spirv/parser_impl.cc +++ b/src/reader/spirv/parser_impl.cc @@ -1166,7 +1166,13 @@ bool ParserImpl::EmitScalarSpecConstants() { ast::DecorationList spec_id_decos; for (const auto& deco : GetDecorationsFor(inst.result_id())) { if ((deco.size() == 2) && (deco[0] == SpvDecorationSpecId)) { - auto* cid = create(Source{}, deco[1]); + const uint32_t id = deco[1]; + if (id > 65535) { + return Fail() << "SpecId too large. WGSL override IDs must be " + "between 0 and 65535: ID %" + << inst.result_id() << " has SpecId " << id; + } + auto* cid = create(Source{}, id); spec_id_decos.push_back(cid); break; } diff --git a/src/reader/spirv/parser_impl_module_var_test.cc b/src/reader/spirv/parser_impl_module_var_test.cc index cc6de3320a..984147cbda 100644 --- a/src/reader/spirv/parser_impl_module_var_test.cc +++ b/src/reader/spirv/parser_impl_module_var_test.cc @@ -2069,6 +2069,35 @@ TEST_F( })")) << module_str; } +TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_Id_TooBig) { + // Override IDs must be between 0 and 65535 + auto p = parser(test::Assemble(Preamble() + FragMain() + R"( + OpDecorate %1 SpecId 65536 + %bool = OpTypeBool + %1 = OpSpecConstantTrue %bool + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + )" + MainBody())); + EXPECT_FALSE(p->Parse()); + EXPECT_EQ(p->error(), + "SpecId too large. WGSL override IDs must be between 0 and 65535: " + "ID %1 has SpecId 65536"); +} + +TEST_F(SpvModuleScopeVarParserTest, + ScalarSpecConstant_DeclareConst_Id_MaxValid) { + // Override IDs must be between 0 and 65535 + auto p = parser(test::Assemble(Preamble() + FragMain() + R"( + OpDecorate %1 SpecId 65535 + %bool = OpTypeBool + %1 = OpSpecConstantTrue %bool + %void = OpTypeVoid + %voidfn = OpTypeFunction %void + )" + MainBody())); + EXPECT_TRUE(p->Parse()); + EXPECT_EQ(p->error(), ""); +} + TEST_F(SpvModuleScopeVarParserTest, ScalarSpecConstant_DeclareConst_True) { auto p = parser(test::Assemble(Preamble() + FragMain() + R"( OpName %c "myconst"