tint: validate max number of case selectors in a switch statement

Bug: tint:1209
Change-Id: Id91901125e7caf9b8b0e297305c26587edaa44d9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/121741
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
Antonio Maiorano 2023-02-27 19:04:23 +00:00
parent 1bb5be9789
commit 43ffb09247
2 changed files with 39 additions and 0 deletions

View File

@ -561,5 +561,36 @@ TEST_F(ResolverControlBlockValidationTest, Switch_OverrideCondition_Fail) {
EXPECT_EQ(r()->error(), "12:34 error: case selector must be a constant expression"); 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<const ast::CaseStatement*, 0> 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<const ast::CaseStatement*, 0> 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
} // namespace tint::resolver } // namespace tint::resolver

View File

@ -77,6 +77,7 @@ namespace tint::resolver {
namespace { namespace {
constexpr size_t kMaxFunctionParameters = 255; constexpr size_t kMaxFunctionParameters = 255;
constexpr size_t kMaxSwitchCaseSelectors = 16383;
bool IsValidStorageTextureDimension(type::TextureDimension dim) { bool IsValidStorageTextureDimension(type::TextureDimension dim) {
switch (dim) { switch (dim) {
@ -2315,6 +2316,13 @@ bool Validator::Return(const ast::ReturnStatement* ret,
} }
bool Validator::SwitchStatement(const ast::SwitchStatement* s) { 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); auto* cond_ty = sem_.TypeOf(s->condition);
if (!cond_ty->is_integer_scalar()) { if (!cond_ty->is_integer_scalar()) {
AddError("switch statement selector expression must be of a scalar integer type", AddError("switch statement selector expression must be of a scalar integer type",