[validation] v-0021: cannot re-assign constants
Bug: tint: 6 Change-Id: Ib5cd57478b35c8dbf04136eb4167a3c3bce1c954 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/26420 Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
parent
65f88d6f1d
commit
e88f1c388c
|
@ -96,6 +96,9 @@ bool ValidatorImpl::ValidateAssign(const ast::AssignmentStatement* a) {
|
||||||
if (!a) {
|
if (!a) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!(ValidateConstant(a))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!(ValidateExpression(a->lhs()) && ValidateExpression(a->rhs()))) {
|
if (!(ValidateExpression(a->lhs()) && ValidateExpression(a->rhs()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -106,6 +109,25 @@ bool ValidatorImpl::ValidateAssign(const ast::AssignmentStatement* a) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ValidatorImpl::ValidateConstant(const ast::AssignmentStatement* assign) {
|
||||||
|
if (!assign) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assign->lhs()->IsIdentifier()) {
|
||||||
|
ast::Variable* var;
|
||||||
|
auto* ident = assign->lhs()->AsIdentifier();
|
||||||
|
if (variable_stack_.get(ident->name(), &var)) {
|
||||||
|
if (var->is_const()) {
|
||||||
|
set_error(assign->source(), "v-0021: cannot re-assign a constant: '" +
|
||||||
|
ident->name() + "'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ValidatorImpl::ValidateResultTypes(const ast::AssignmentStatement* a) {
|
bool ValidatorImpl::ValidateResultTypes(const ast::AssignmentStatement* a) {
|
||||||
if (!a->lhs()->result_type() || !a->rhs()->result_type()) {
|
if (!a->lhs()->result_type() || !a->rhs()->result_type()) {
|
||||||
set_error(a->source(), "result_type() is nullptr");
|
set_error(a->source(), "result_type() is nullptr");
|
||||||
|
|
|
@ -66,9 +66,9 @@ class ValidatorImpl {
|
||||||
/// @returns true if the validation was successful
|
/// @returns true if the validation was successful
|
||||||
bool ValidateStatement(const ast::Statement* stmt);
|
bool ValidateStatement(const ast::Statement* stmt);
|
||||||
/// Validates an assignment
|
/// Validates an assignment
|
||||||
/// @param a the assignment to check
|
/// @param assign the assignment to check
|
||||||
/// @returns true if the validation was successful
|
/// @returns true if the validation was successful
|
||||||
bool ValidateAssign(const ast::AssignmentStatement* a);
|
bool ValidateAssign(const ast::AssignmentStatement* assign);
|
||||||
/// Validates v-0001: Only allowed import is "GLSL.std.450"
|
/// Validates v-0001: Only allowed import is "GLSL.std.450"
|
||||||
/// @param module the modele to check imports
|
/// @param module the modele to check imports
|
||||||
/// @returns ture if input complies with v-0001 rule
|
/// @returns ture if input complies with v-0001 rule
|
||||||
|
@ -82,9 +82,13 @@ class ValidatorImpl {
|
||||||
/// @return true if idnet was defined
|
/// @return true if idnet was defined
|
||||||
bool ValidateIdentifier(const ast::IdentifierExpression* ident);
|
bool ValidateIdentifier(const ast::IdentifierExpression* ident);
|
||||||
/// Validates if the input follows type checking rules
|
/// Validates if the input follows type checking rules
|
||||||
/// @param 'a' the assignment to check
|
/// @param assign the assignment to check
|
||||||
/// @returns ture if successful
|
/// @returns ture if successful
|
||||||
bool ValidateResultTypes(const ast::AssignmentStatement* a);
|
bool ValidateResultTypes(const ast::AssignmentStatement* assign);
|
||||||
|
/// Validate v-0021: Cannot re-assign a constant
|
||||||
|
/// @param assign is the assigment to check if its lhs is a const
|
||||||
|
/// @returns false if lhs of assign is a constant identifier
|
||||||
|
bool ValidateConstant(const ast::AssignmentStatement* assign);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string error_;
|
std::string error_;
|
||||||
|
|
|
@ -413,27 +413,36 @@ TEST_F(ValidatorTest, UnsingUndefinedVariableOuterScope_Pass) {
|
||||||
EXPECT_TRUE(v.ValidateStatements(outer_body.get())) << v.error();
|
EXPECT_TRUE(v.ValidateStatements(outer_body.get())) << v.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ValidatorTest, DISABLED_AssignToConstant_Fail) {
|
TEST_F(ValidatorTest, AssignToConstant_Fail) {
|
||||||
// v-0021: Cannot re-assign a constant.
|
// {
|
||||||
// const a :i32 = 1;
|
// const a :i32 = 2;
|
||||||
// a = 2;
|
// a = 2
|
||||||
|
// }
|
||||||
ast::type::I32Type i32;
|
ast::type::I32Type i32;
|
||||||
|
auto var =
|
||||||
|
std::make_unique<ast::Variable>("a", ast::StorageClass::kNone, &i32);
|
||||||
|
var->set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
|
||||||
|
std::make_unique<ast::SintLiteral>(&i32, 2)));
|
||||||
|
var->set_is_const(true);
|
||||||
|
|
||||||
ast::Variable var("a", ast::StorageClass::kPrivate, &i32);
|
|
||||||
var.set_constructor(std::make_unique<ast::ScalarConstructorExpression>(
|
|
||||||
std::make_unique<ast::SintLiteral>(&i32, 1)));
|
|
||||||
var.set_is_const(true);
|
|
||||||
auto lhs = std::make_unique<ast::IdentifierExpression>("a");
|
auto lhs = std::make_unique<ast::IdentifierExpression>("a");
|
||||||
|
auto* lhs_ptr = lhs.get();
|
||||||
auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
|
auto rhs = std::make_unique<ast::ScalarConstructorExpression>(
|
||||||
std::make_unique<ast::SintLiteral>(&i32, 2));
|
std::make_unique<ast::SintLiteral>(&i32, 2));
|
||||||
|
auto* rhs_ptr = rhs.get();
|
||||||
|
|
||||||
ast::AssignmentStatement assign(std::move(lhs), std::move(rhs));
|
auto body = std::make_unique<ast::BlockStatement>();
|
||||||
|
body->append(std::make_unique<ast::VariableDeclStatement>(std::move(var)));
|
||||||
|
body->append(std::make_unique<ast::AssignmentStatement>(
|
||||||
|
Source{12, 34}, std::move(lhs), std::move(rhs)));
|
||||||
|
|
||||||
|
EXPECT_TRUE(td()->DetermineStatements(body.get())) << td()->error();
|
||||||
|
ASSERT_NE(lhs_ptr->result_type(), nullptr);
|
||||||
|
ASSERT_NE(rhs_ptr->result_type(), nullptr);
|
||||||
|
|
||||||
tint::ValidatorImpl v;
|
tint::ValidatorImpl v;
|
||||||
// TODO(SarahM0): Invalidate assignments to a constant.
|
EXPECT_FALSE(v.ValidateStatements(body.get()));
|
||||||
ASSERT_TRUE(v.has_error());
|
EXPECT_EQ(v.error(), "12:34: v-0021: cannot re-assign a constant: 'a'");
|
||||||
EXPECT_EQ(v.error(), "2:1: v-0021: cannot re-assign a constant");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in New Issue