validation: validate function parameters
A function parameter of pointer type must be in one of the following storage classes: - function - private - workgroup A function parameter must one the following types: - atomic-free plain type - a pointer type - a texture type - a sampler type Bug: tint:896 tint:894 Change-Id: Id8cec1bdc8e5be2c8c18a8420cec8f13f6aeddd0 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/55940 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
5a88ec8822
commit
9432c97070
|
@ -521,5 +521,65 @@ TEST_F(ResolverFunctionValidationTest, ReturnIsAtomicFreePlain_StructOfAtomic) {
|
||||||
"12:34 error: function return type must be an atomic-free plain type");
|
"12:34 error: function return type must be an atomic-free plain type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverFunctionValidationTest, ParameterSotreType_NonAtomicFree) {
|
||||||
|
Structure("S", {Member("m", ty.atomic(ty.i32()))});
|
||||||
|
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
|
||||||
|
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
|
||||||
|
Func("f", ast::VariableList{bar}, ty.void_(), {});
|
||||||
|
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
"12:34 error: store type of function parameter must be an "
|
||||||
|
"atomic-free type");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ResolverFunctionValidationTest, ParameterSotreType_AtomicFree) {
|
||||||
|
Structure("S", {Member("m", ty.i32())});
|
||||||
|
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
|
||||||
|
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
|
||||||
|
Func("f", ast::VariableList{bar}, ty.void_(), {});
|
||||||
|
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TestParams {
|
||||||
|
ast::StorageClass storage_class;
|
||||||
|
bool should_pass;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TestWithParams : resolver::ResolverTestWithParam<TestParams> {};
|
||||||
|
|
||||||
|
using ResolverFunctionParameterValidationTest = TestWithParams;
|
||||||
|
TEST_P(ResolverFunctionParameterValidationTest, SotrageClass) {
|
||||||
|
auto& param = GetParam();
|
||||||
|
auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.storage_class);
|
||||||
|
auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
|
||||||
|
Func("f", ast::VariableList{arg}, ty.void_(), {});
|
||||||
|
|
||||||
|
if (param.should_pass) {
|
||||||
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
} else {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << param.storage_class;
|
||||||
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
EXPECT_EQ(r()->error(),
|
||||||
|
"12:34 error: function parameter of pointer type cannot be in '" +
|
||||||
|
ss.str() + "' storage class");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INSTANTIATE_TEST_SUITE_P(
|
||||||
|
ResolverTest,
|
||||||
|
ResolverFunctionParameterValidationTest,
|
||||||
|
testing::Values(TestParams{ast::StorageClass::kNone, false},
|
||||||
|
TestParams{ast::StorageClass::kInput, false},
|
||||||
|
TestParams{ast::StorageClass::kOutput, false},
|
||||||
|
TestParams{ast::StorageClass::kUniform, false},
|
||||||
|
TestParams{ast::StorageClass::kWorkgroup, true},
|
||||||
|
TestParams{ast::StorageClass::kUniformConstant, false},
|
||||||
|
TestParams{ast::StorageClass::kStorage, false},
|
||||||
|
TestParams{ast::StorageClass::kImage, false},
|
||||||
|
TestParams{ast::StorageClass::kPrivate, true},
|
||||||
|
TestParams{ast::StorageClass::kFunction, true}));
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -916,8 +916,8 @@ bool Resolver::ValidateVariable(const VariableInfo* info) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resolver::ValidateParameter(const ast::Function* func,
|
bool Resolver::ValidateFunctionParameter(const ast::Function* func,
|
||||||
const VariableInfo* info) {
|
const VariableInfo* info) {
|
||||||
if (!ValidateVariable(info)) {
|
if (!ValidateVariable(info)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -953,6 +953,36 @@ bool Resolver::ValidateParameter(const ast::Function* func,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto* ref = info->type->As<sem::Pointer>()) {
|
||||||
|
auto sc = ref->StorageClass();
|
||||||
|
if (!(sc == ast::StorageClass::kFunction ||
|
||||||
|
sc == ast::StorageClass::kPrivate ||
|
||||||
|
sc == ast::StorageClass::kWorkgroup)) {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "function parameter of pointer type cannot be in '" << sc
|
||||||
|
<< "' storage class";
|
||||||
|
AddError(ss.str(), info->declaration->source());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsPlain(info->type)) {
|
||||||
|
if (!IsAtomicFreePlain(info->type) &&
|
||||||
|
!IsValidationDisabled(
|
||||||
|
info->declaration->decorations(),
|
||||||
|
ast::DisabledValidation::kIgnoreAtomicFunctionParameter)) {
|
||||||
|
AddError("store type of function parameter must be an atomic-free type",
|
||||||
|
info->declaration->source());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!info->type->IsAnyOf<sem::Texture, sem::Sampler, sem::Pointer>()) {
|
||||||
|
AddError("store type of function parameter cannot be " +
|
||||||
|
info->type->FriendlyName(builder_->Symbols()),
|
||||||
|
info->declaration->source());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,7 +1107,7 @@ bool Resolver::ValidateFunction(const ast::Function* func,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto* param : func->params()) {
|
for (auto* param : func->params()) {
|
||||||
if (!ValidateParameter(func, variable_to_info_.at(param))) {
|
if (!ValidateFunctionParameter(func, variable_to_info_.at(param))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,7 +281,8 @@ class Resolver {
|
||||||
bool ValidateMatrix(const sem::Matrix* matirx_type, const Source& source);
|
bool ValidateMatrix(const sem::Matrix* matirx_type, const Source& source);
|
||||||
bool ValidateMatrixConstructor(const ast::TypeConstructorExpression* ctor,
|
bool ValidateMatrixConstructor(const ast::TypeConstructorExpression* ctor,
|
||||||
const sem::Matrix* matrix_type);
|
const sem::Matrix* matrix_type);
|
||||||
bool ValidateParameter(const ast::Function* func, const VariableInfo* info);
|
bool ValidateFunctionParameter(const ast::Function* func,
|
||||||
|
const VariableInfo* info);
|
||||||
bool ValidateReturn(const ast::ReturnStatement* ret);
|
bool ValidateReturn(const ast::ReturnStatement* ret);
|
||||||
bool ValidateStatements(const ast::StatementList& stmts);
|
bool ValidateStatements(const ast::StatementList& stmts);
|
||||||
bool ValidateStorageTexture(const ast::StorageTexture* t);
|
bool ValidateStorageTexture(const ast::StorageTexture* t);
|
||||||
|
|
Loading…
Reference in New Issue