diff --git a/src/tint/resolver/control_block_validation_test.cc b/src/tint/resolver/control_block_validation_test.cc index 2104321a18..ba7aa53490 100644 --- a/src/tint/resolver/control_block_validation_test.cc +++ b/src/tint/resolver/control_block_validation_test.cc @@ -561,5 +561,36 @@ TEST_F(ResolverControlBlockValidationTest, Switch_OverrideCondition_Fail) { EXPECT_EQ(r()->error(), "12:34 error: case selector must be a constant expression"); } +constexpr size_t kMaxSwitchCaseSelectors = 16383; + +TEST_F(ResolverControlBlockValidationTest, Switch_MaxSelectors_Valid) { + utils::Vector cases; + for (size_t i = 0; i < kMaxSwitchCaseSelectors - 1; ++i) { + cases.Push(Case(CaseSelector(Expr(i32(i))))); + } + cases.Push(DefaultCase()); + + auto* var = Var("a", ty.i32()); + auto* s = Switch("a", std::move(cases)); + WrapInFunction(var, s); + + EXPECT_TRUE(r()->Resolve()) << r()->error(); +} + +TEST_F(ResolverControlBlockValidationTest, Switch_MaxSelectors_Invalid) { + utils::Vector cases; + for (size_t i = 0; i < kMaxSwitchCaseSelectors; ++i) { + cases.Push(Case(CaseSelector(Expr(i32(i))))); + } + cases.Push(DefaultCase()); + + auto* var = Var("a", ty.i32()); + auto* s = Switch(Source{{12, 34}}, "a", std::move(cases)); + WrapInFunction(var, s); + + EXPECT_FALSE(r()->Resolve()); + EXPECT_EQ(r()->error(), "12:34 error: switch statement has 16384 case selectors, max is 16383"); +} + } // namespace } // namespace tint::resolver diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index 6ae5ce28f5..6419999635 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc @@ -77,6 +77,7 @@ namespace tint::resolver { namespace { constexpr size_t kMaxFunctionParameters = 255; +constexpr size_t kMaxSwitchCaseSelectors = 16383; bool IsValidStorageTextureDimension(type::TextureDimension dim) { switch (dim) { @@ -2315,6 +2316,13 @@ bool Validator::Return(const ast::ReturnStatement* ret, } bool Validator::SwitchStatement(const ast::SwitchStatement* s) { + if (s->body.Length() > kMaxSwitchCaseSelectors) { + AddError("switch statement has " + std::to_string(s->body.Length()) + + " case selectors, max is " + std::to_string(kMaxSwitchCaseSelectors), + s->source); + return false; + } + auto* cond_ty = sem_.TypeOf(s->condition); if (!cond_ty->is_integer_scalar()) { AddError("switch statement selector expression must be of a scalar integer type",