ast: Validate that ASTs are all part of the same program
Assert in each AST constructor that child nodes belong to the program of the parent. Bug: tint:709 Change-Id: Icc89b69691d099e358ff632a0ca6fd7943cb0193 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47623 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Reviewed-by: James Price <jrprice@google.com> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
31804e09ed
commit
f0c816a757
|
@ -27,7 +27,9 @@ ArrayAccessorExpression::ArrayAccessorExpression(ProgramID program_id,
|
||||||
Expression* idx_expr)
|
Expression* idx_expr)
|
||||||
: Base(program_id, source), array_(array), idx_expr_(idx_expr) {
|
: Base(program_id, source), array_(array), idx_expr_(idx_expr) {
|
||||||
TINT_ASSERT(array_);
|
TINT_ASSERT(array_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(array_, program_id);
|
||||||
TINT_ASSERT(idx_expr_);
|
TINT_ASSERT(idx_expr_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(idx_expr_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) =
|
ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) =
|
||||||
|
|
|
@ -49,7 +49,7 @@ TEST_F(ArrayAccessorExpressionTest, IsArrayAccessor) {
|
||||||
EXPECT_TRUE(exp->Is<ArrayAccessorExpression>());
|
EXPECT_TRUE(exp->Is<ArrayAccessorExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, Assert_NullArray) {
|
TEST_F(ArrayAccessorExpressionTest, Assert_Null_Array) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -58,7 +58,7 @@ TEST_F(ArrayAccessorExpressionTest, Assert_NullArray) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, Assert_NullIndex) {
|
TEST_F(ArrayAccessorExpressionTest, Assert_Null_Index) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -67,6 +67,26 @@ TEST_F(ArrayAccessorExpressionTest, Assert_NullIndex) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ArrayAccessorExpressionTest, Assert_DifferentProgramID_Array) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<ArrayAccessorExpression>(b2.Expr("arr"), b1.Expr("idx"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ArrayAccessorExpressionTest, Assert_DifferentProgramID_Index) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<ArrayAccessorExpression>(b1.Expr("arr"), b2.Expr("idx"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ArrayAccessorExpressionTest, ToStr) {
|
TEST_F(ArrayAccessorExpressionTest, ToStr) {
|
||||||
auto* ary = Expr("ary");
|
auto* ary = Expr("ary");
|
||||||
auto* idx = Expr("idx");
|
auto* idx = Expr("idx");
|
||||||
|
|
|
@ -27,7 +27,9 @@ AssignmentStatement::AssignmentStatement(ProgramID program_id,
|
||||||
Expression* rhs)
|
Expression* rhs)
|
||||||
: Base(program_id, source), lhs_(lhs), rhs_(rhs) {
|
: Base(program_id, source), lhs_(lhs), rhs_(rhs) {
|
||||||
TINT_ASSERT(lhs_);
|
TINT_ASSERT(lhs_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(lhs_, program_id);
|
||||||
TINT_ASSERT(rhs_);
|
TINT_ASSERT(rhs_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(rhs_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;
|
AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;
|
||||||
|
|
|
@ -51,7 +51,7 @@ TEST_F(AssignmentStatementTest, IsAssign) {
|
||||||
EXPECT_TRUE(stmt->Is<AssignmentStatement>());
|
EXPECT_TRUE(stmt->Is<AssignmentStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AssignmentStatementTest, Assert_NullLHS) {
|
TEST_F(AssignmentStatementTest, Assert_Null_LHS) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -60,7 +60,7 @@ TEST_F(AssignmentStatementTest, Assert_NullLHS) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AssignmentStatementTest, Assert_NullRHS) {
|
TEST_F(AssignmentStatementTest, Assert_Null_RHS) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -69,6 +69,26 @@ TEST_F(AssignmentStatementTest, Assert_NullRHS) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(AssignmentStatementTest, Assert_DifferentProgramID_LHS) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<AssignmentStatement>(b2.Expr("lhs"), b1.Expr("rhs"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssignmentStatementTest, Assert_DifferentProgramID_RHS) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<AssignmentStatement>(b1.Expr("lhs"), b2.Expr("rhs"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(AssignmentStatementTest, ToStr) {
|
TEST_F(AssignmentStatementTest, ToStr) {
|
||||||
auto* lhs = Expr("lhs");
|
auto* lhs = Expr("lhs");
|
||||||
auto* rhs = Expr("rhs");
|
auto* rhs = Expr("rhs");
|
||||||
|
|
|
@ -28,7 +28,9 @@ BinaryExpression::BinaryExpression(ProgramID program_id,
|
||||||
Expression* rhs)
|
Expression* rhs)
|
||||||
: Base(program_id, source), op_(op), lhs_(lhs), rhs_(rhs) {
|
: Base(program_id, source), op_(op), lhs_(lhs), rhs_(rhs) {
|
||||||
TINT_ASSERT(lhs_);
|
TINT_ASSERT(lhs_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(lhs_, program_id);
|
||||||
TINT_ASSERT(rhs_);
|
TINT_ASSERT(rhs_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(rhs_, program_id);
|
||||||
TINT_ASSERT(op_ != BinaryOp::kNone);
|
TINT_ASSERT(op_ != BinaryOp::kNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ TEST_F(BinaryExpressionTest, IsBinary) {
|
||||||
EXPECT_TRUE(r->Is<BinaryExpression>());
|
EXPECT_TRUE(r->Is<BinaryExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
|
TEST_F(BinaryExpressionTest, Assert_Null_LHS) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -59,7 +59,7 @@ TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
|
TEST_F(BinaryExpressionTest, Assert_Null_RHS) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -68,6 +68,28 @@ TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BinaryExpressionTest, Assert_DifferentProgramID_LHS) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<BinaryExpression>(BinaryOp::kEqual, b2.Expr("lhs"),
|
||||||
|
b1.Expr("rhs"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(BinaryExpressionTest, Assert_DifferentProgramID_RHS) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<BinaryExpression>(BinaryOp::kEqual, b1.Expr("lhs"),
|
||||||
|
b2.Expr("rhs"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(BinaryExpressionTest, ToStr) {
|
TEST_F(BinaryExpressionTest, ToStr) {
|
||||||
auto* lhs = Expr("lhs");
|
auto* lhs = Expr("lhs");
|
||||||
auto* rhs = Expr("rhs");
|
auto* rhs = Expr("rhs");
|
||||||
|
|
|
@ -28,6 +28,7 @@ BitcastExpression::BitcastExpression(ProgramID program_id,
|
||||||
: Base(program_id, source), type_(type), expr_(expr) {
|
: Base(program_id, source), type_(type), expr_(expr) {
|
||||||
TINT_ASSERT(type_);
|
TINT_ASSERT(type_);
|
||||||
TINT_ASSERT(expr_);
|
TINT_ASSERT(expr_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(expr, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
BitcastExpression::BitcastExpression(BitcastExpression&&) = default;
|
BitcastExpression::BitcastExpression(BitcastExpression&&) = default;
|
||||||
|
|
|
@ -48,7 +48,7 @@ TEST_F(BitcastExpressionTest, IsBitcast) {
|
||||||
EXPECT_TRUE(exp->Is<BitcastExpression>());
|
EXPECT_TRUE(exp->Is<BitcastExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BitcastExpressionTest, Assert_NullType) {
|
TEST_F(BitcastExpressionTest, Assert_Null_Type) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -57,7 +57,7 @@ TEST_F(BitcastExpressionTest, Assert_NullType) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BitcastExpressionTest, Assert_NullExpr) {
|
TEST_F(BitcastExpressionTest, Assert_Null_Expr) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -66,6 +66,16 @@ TEST_F(BitcastExpressionTest, Assert_NullExpr) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BitcastExpressionTest, Assert_DifferentProgramID_Expr) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<BitcastExpression>(b1.ty.f32(), b2.Expr("idx"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(BitcastExpressionTest, ToStr) {
|
TEST_F(BitcastExpressionTest, ToStr) {
|
||||||
auto* expr = Expr("expr");
|
auto* expr = Expr("expr");
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ BlockStatement::BlockStatement(ProgramID program_id,
|
||||||
: Base(program_id, source), statements_(std::move(statements)) {
|
: Base(program_id, source), statements_(std::move(statements)) {
|
||||||
for (auto* stmt : *this) {
|
for (auto* stmt : *this) {
|
||||||
TINT_ASSERT(stmt);
|
TINT_ASSERT(stmt);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(stmt, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ TEST_F(BlockStatementTest, IsBlock) {
|
||||||
EXPECT_TRUE(b->Is<BlockStatement>());
|
EXPECT_TRUE(b->Is<BlockStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BlockStatementTest, Assert_NullStatement) {
|
TEST_F(BlockStatementTest, Assert_Null_Statement) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -55,6 +55,17 @@ TEST_F(BlockStatementTest, Assert_NullStatement) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(BlockStatementTest, Assert_DifferentProgramID_Statement) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<BlockStatement>(
|
||||||
|
ast::StatementList{b2.create<DiscardStatement>()});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(BlockStatementTest, ToStr) {
|
TEST_F(BlockStatementTest, ToStr) {
|
||||||
auto* b = create<BlockStatement>(ast::StatementList{
|
auto* b = create<BlockStatement>(ast::StatementList{
|
||||||
create<DiscardStatement>(),
|
create<DiscardStatement>(),
|
||||||
|
|
|
@ -27,8 +27,10 @@ CallExpression::CallExpression(ProgramID program_id,
|
||||||
ExpressionList params)
|
ExpressionList params)
|
||||||
: Base(program_id, source), func_(func), params_(params) {
|
: Base(program_id, source), func_(func), params_(params) {
|
||||||
TINT_ASSERT(func_);
|
TINT_ASSERT(func_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(func_, program_id);
|
||||||
for (auto* param : params_) {
|
for (auto* param : params_) {
|
||||||
TINT_ASSERT(param);
|
TINT_ASSERT(param);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(param, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ TEST_F(CallExpressionTest, IsCall) {
|
||||||
EXPECT_TRUE(stmt->Is<CallExpression>());
|
EXPECT_TRUE(stmt->Is<CallExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CallExpressionTest, Assert_NullFunction) {
|
TEST_F(CallExpressionTest, Assert_Null_Function) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -60,7 +60,7 @@ TEST_F(CallExpressionTest, Assert_NullFunction) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CallExpressionTest, Assert_NullParam) {
|
TEST_F(CallExpressionTest, Assert_Null_Param) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -73,6 +73,27 @@ TEST_F(CallExpressionTest, Assert_NullParam) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CallExpressionTest, Assert_DifferentProgramID_Function) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<CallExpression>(b2.Expr("func"), ExpressionList{});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CallExpressionTest, Assert_DifferentProgramID_Param) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<CallExpression>(b1.Expr("func"),
|
||||||
|
ExpressionList{b2.Expr("param1")});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CallExpressionTest, ToStr_NoParams) {
|
TEST_F(CallExpressionTest, ToStr_NoParams) {
|
||||||
auto* func = Expr("func");
|
auto* func = Expr("func");
|
||||||
auto* stmt = create<CallExpression>(func, ExpressionList{});
|
auto* stmt = create<CallExpression>(func, ExpressionList{});
|
||||||
|
|
|
@ -26,6 +26,7 @@ CallStatement::CallStatement(ProgramID program_id,
|
||||||
CallExpression* call)
|
CallExpression* call)
|
||||||
: Base(program_id, source), call_(call) {
|
: Base(program_id, source), call_(call) {
|
||||||
TINT_ASSERT(call_);
|
TINT_ASSERT(call_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(call_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallStatement::CallStatement(CallStatement&&) = default;
|
CallStatement::CallStatement(CallStatement&&) = default;
|
||||||
|
|
|
@ -35,7 +35,7 @@ TEST_F(CallStatementTest, IsCall) {
|
||||||
EXPECT_TRUE(c->Is<CallStatement>());
|
EXPECT_TRUE(c->Is<CallStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CallStatementTest, Assert_NullCall) {
|
TEST_F(CallStatementTest, Assert_Null_Call) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -44,6 +44,17 @@ TEST_F(CallStatementTest, Assert_NullCall) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CallStatementTest, Assert_DifferentProgramID_Call) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<CallStatement>(
|
||||||
|
b2.create<CallExpression>(b2.Expr("func"), ExpressionList{}));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CallStatementTest, ToStr) {
|
TEST_F(CallStatementTest, ToStr) {
|
||||||
auto* c = create<CallStatement>(
|
auto* c = create<CallStatement>(
|
||||||
create<CallExpression>(Expr("func"), ExpressionList{}));
|
create<CallExpression>(Expr("func"), ExpressionList{}));
|
||||||
|
|
|
@ -27,6 +27,11 @@ CaseStatement::CaseStatement(ProgramID program_id,
|
||||||
BlockStatement* body)
|
BlockStatement* body)
|
||||||
: Base(program_id, source), selectors_(selectors), body_(body) {
|
: Base(program_id, source), selectors_(selectors), body_(body) {
|
||||||
TINT_ASSERT(body_);
|
TINT_ASSERT(body_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(body_, program_id);
|
||||||
|
for (auto* selector : selectors) {
|
||||||
|
TINT_ASSERT(selector);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(selector, program_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CaseStatement::CaseStatement(CaseStatement&&) = default;
|
CaseStatement::CaseStatement(CaseStatement&&) = default;
|
||||||
|
|
|
@ -90,7 +90,7 @@ TEST_F(CaseStatementTest, IsCase) {
|
||||||
EXPECT_TRUE(c->Is<CaseStatement>());
|
EXPECT_TRUE(c->Is<CaseStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, Assert_NullBody) {
|
TEST_F(CaseStatementTest, Assert_Null_Body) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -99,6 +99,39 @@ TEST_F(CaseStatementTest, Assert_NullBody) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CaseStatementTest, Assert_Null_Selector) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b;
|
||||||
|
b.create<CaseStatement>(CaseSelectorList{nullptr},
|
||||||
|
b.create<BlockStatement>(StatementList{}));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CaseStatementTest, Assert_DifferentProgramID_Call) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<CaseStatement>(CaseSelectorList{},
|
||||||
|
b2.create<BlockStatement>(StatementList{}));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(CaseStatementTest, Assert_DifferentProgramID_Selector) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<CaseStatement>(
|
||||||
|
CaseSelectorList{b2.create<SintLiteral>(b2.ty.i32(), 2)},
|
||||||
|
b1.create<BlockStatement>(StatementList{}));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
|
TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) {
|
||||||
CaseSelectorList b;
|
CaseSelectorList b;
|
||||||
b.push_back(create<SintLiteral>(ty.i32(), -2));
|
b.push_back(create<SintLiteral>(ty.i32(), -2));
|
||||||
|
|
|
@ -27,6 +27,8 @@ ElseStatement::ElseStatement(ProgramID program_id,
|
||||||
BlockStatement* body)
|
BlockStatement* body)
|
||||||
: Base(program_id, source), condition_(condition), body_(body) {
|
: Base(program_id, source), condition_(condition), body_(body) {
|
||||||
TINT_ASSERT(body_);
|
TINT_ASSERT(body_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(body_, program_id);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(condition_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElseStatement::ElseStatement(ElseStatement&&) = default;
|
ElseStatement::ElseStatement(ElseStatement&&) = default;
|
||||||
|
|
|
@ -38,32 +38,29 @@ TEST_F(ElseStatementTest, Creation) {
|
||||||
|
|
||||||
TEST_F(ElseStatementTest, Creation_WithSource) {
|
TEST_F(ElseStatementTest, Creation_WithSource) {
|
||||||
auto* e = create<ElseStatement>(Source{Source::Location{20, 2}}, Expr(true),
|
auto* e = create<ElseStatement>(Source{Source::Location{20, 2}}, Expr(true),
|
||||||
create<BlockStatement>(StatementList{}));
|
Block());
|
||||||
auto src = e->source();
|
auto src = e->source();
|
||||||
EXPECT_EQ(src.range.begin.line, 20u);
|
EXPECT_EQ(src.range.begin.line, 20u);
|
||||||
EXPECT_EQ(src.range.begin.column, 2u);
|
EXPECT_EQ(src.range.begin.column, 2u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElseStatementTest, IsElse) {
|
TEST_F(ElseStatementTest, IsElse) {
|
||||||
auto* e =
|
auto* e = create<ElseStatement>(nullptr, Block());
|
||||||
create<ElseStatement>(nullptr, create<BlockStatement>(StatementList{}));
|
|
||||||
EXPECT_TRUE(e->Is<ElseStatement>());
|
EXPECT_TRUE(e->Is<ElseStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElseStatementTest, HasCondition) {
|
TEST_F(ElseStatementTest, HasCondition) {
|
||||||
auto* cond = Expr(true);
|
auto* cond = Expr(true);
|
||||||
auto* e =
|
auto* e = create<ElseStatement>(cond, Block());
|
||||||
create<ElseStatement>(cond, create<BlockStatement>(StatementList{}));
|
|
||||||
EXPECT_TRUE(e->HasCondition());
|
EXPECT_TRUE(e->HasCondition());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElseStatementTest, HasContition_NullCondition) {
|
TEST_F(ElseStatementTest, HasContition_NullCondition) {
|
||||||
auto* e =
|
auto* e = create<ElseStatement>(nullptr, Block());
|
||||||
create<ElseStatement>(nullptr, create<BlockStatement>(StatementList{}));
|
|
||||||
EXPECT_FALSE(e->HasCondition());
|
EXPECT_FALSE(e->HasCondition());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ElseStatementTest, Assert_NullBody) {
|
TEST_F(ElseStatementTest, Assert_Null_Body) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -72,6 +69,26 @@ TEST_F(ElseStatementTest, Assert_NullBody) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ElseStatementTest, Assert_DifferentProgramID_Condition) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<ElseStatement>(b2.Expr(true), b1.Block());
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ElseStatementTest, Assert_DifferentProgramID_Body) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<ElseStatement>(b1.Expr(true), b2.Block());
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ElseStatementTest, ToStr) {
|
TEST_F(ElseStatementTest, ToStr) {
|
||||||
auto* cond = Expr(true);
|
auto* cond = Expr(true);
|
||||||
auto* body = create<BlockStatement>(StatementList{
|
auto* body = create<BlockStatement>(StatementList{
|
||||||
|
|
|
@ -38,11 +38,19 @@ Function::Function(ProgramID program_id,
|
||||||
body_(body),
|
body_(body),
|
||||||
decorations_(std::move(decorations)),
|
decorations_(std::move(decorations)),
|
||||||
return_type_decorations_(std::move(return_type_decorations)) {
|
return_type_decorations_(std::move(return_type_decorations)) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(body, program_id);
|
||||||
for (auto* param : params_) {
|
for (auto* param : params_) {
|
||||||
TINT_ASSERT(param && param->is_const());
|
TINT_ASSERT(param && param->is_const());
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(param, program_id);
|
||||||
}
|
}
|
||||||
TINT_ASSERT(symbol_.IsValid());
|
TINT_ASSERT(symbol_.IsValid());
|
||||||
TINT_ASSERT(return_type_);
|
TINT_ASSERT(return_type_);
|
||||||
|
for (auto* deco : decorations_) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(deco, program_id);
|
||||||
|
}
|
||||||
|
for (auto* deco : return_type_decorations_) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(deco, program_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Function::Function(Function&&) = default;
|
Function::Function(Function&&) = default;
|
||||||
|
|
|
@ -57,7 +57,7 @@ TEST_F(FunctionTest, Assert_InvalidName) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(FunctionTest, Assert_NullReturnType) {
|
TEST_F(FunctionTest, Assert_Null_ReturnType) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -66,7 +66,7 @@ TEST_F(FunctionTest, Assert_NullReturnType) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(FunctionTest, Assert_NullParam) {
|
TEST_F(FunctionTest, Assert_Null_Param) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -79,6 +79,44 @@ TEST_F(FunctionTest, Assert_NullParam) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(FunctionTest, Assert_DifferentProgramID_Param) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.Func("func", VariableList{b2.Param("var", b2.ty.i32())},
|
||||||
|
b1.ty.void_(), StatementList{});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FunctionTest, Assert_DifferentProgramID_Deco) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
||||||
|
DecorationList{
|
||||||
|
b2.create<WorkgroupDecoration>(2, 4, 6),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnDeco) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
||||||
|
DecorationList{},
|
||||||
|
DecorationList{
|
||||||
|
b2.create<WorkgroupDecoration>(2, 4, 6),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(FunctionTest, Assert_NonConstParam) {
|
TEST_F(FunctionTest, Assert_NonConstParam) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,9 +31,12 @@ IfStatement::IfStatement(ProgramID program_id,
|
||||||
body_(body),
|
body_(body),
|
||||||
else_statements_(std::move(else_stmts)) {
|
else_statements_(std::move(else_stmts)) {
|
||||||
TINT_ASSERT(condition_);
|
TINT_ASSERT(condition_);
|
||||||
TINT_ASSERT(body);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(condition_, program_id);
|
||||||
|
TINT_ASSERT(body_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(body_, program_id);
|
||||||
for (auto* el : else_statements_) {
|
for (auto* el : else_statements_) {
|
||||||
TINT_ASSERT(el);
|
TINT_ASSERT(el);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(el, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,8 @@ using IfStatementTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(IfStatementTest, Creation) {
|
TEST_F(IfStatementTest, Creation) {
|
||||||
auto* cond = Expr("cond");
|
auto* cond = Expr("cond");
|
||||||
auto* body =
|
auto* stmt = create<IfStatement>(Source{Source::Location{20, 2}}, cond,
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
Block(create<DiscardStatement>()),
|
||||||
auto* stmt = create<IfStatement>(Source{Source::Location{20, 2}}, cond, body,
|
|
||||||
ElseStatementList{});
|
ElseStatementList{});
|
||||||
auto src = stmt->source();
|
auto src = stmt->source();
|
||||||
EXPECT_EQ(src.range.begin.line, 20u);
|
EXPECT_EQ(src.range.begin.line, 20u);
|
||||||
|
@ -36,22 +35,20 @@ TEST_F(IfStatementTest, Creation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IfStatementTest, IsIf) {
|
TEST_F(IfStatementTest, IsIf) {
|
||||||
auto* stmt = create<IfStatement>(
|
auto* stmt = create<IfStatement>(Expr(true), Block(), ElseStatementList{});
|
||||||
Expr(true), create<BlockStatement>(StatementList{}), ElseStatementList{});
|
|
||||||
EXPECT_TRUE(stmt->Is<IfStatement>());
|
EXPECT_TRUE(stmt->Is<IfStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IfStatementTest, Assert_NullCondition) {
|
TEST_F(IfStatementTest, Assert_Null_Condition) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
auto* body = b.create<BlockStatement>(StatementList{});
|
b.create<IfStatement>(nullptr, b.Block(), ElseStatementList{});
|
||||||
b.create<IfStatement>(nullptr, body, ElseStatementList{});
|
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IfStatementTest, Assert_NullBody) {
|
TEST_F(IfStatementTest, Assert_Null_Body) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -60,7 +57,7 @@ TEST_F(IfStatementTest, Assert_NullBody) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(IfStatementTest, Assert_NullElseStatement) {
|
TEST_F(IfStatementTest, Assert_Null_ElseStatement) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -70,11 +67,44 @@ TEST_F(IfStatementTest, Assert_NullElseStatement) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(IfStatementTest, Assert_DifferentProgramID_Cond) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<IfStatement>(b2.Expr(true), b1.Block(), ElseStatementList{});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IfStatementTest, Assert_DifferentProgramID_Body) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<IfStatement>(b1.Expr(true), b2.Block(), ElseStatementList{});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(IfStatementTest, Assert_DifferentProgramID_ElseStatement) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<IfStatement>(
|
||||||
|
b1.Expr(true), b1.Block(),
|
||||||
|
ElseStatementList{
|
||||||
|
b2.create<ElseStatement>(b2.Expr("ident"), b2.Block()),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(IfStatementTest, ToStr) {
|
TEST_F(IfStatementTest, ToStr) {
|
||||||
auto* cond = Expr("cond");
|
auto* cond = Expr("cond");
|
||||||
auto* body =
|
auto* stmt = create<IfStatement>(cond, Block(create<DiscardStatement>()),
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
ElseStatementList{});
|
||||||
auto* stmt = create<IfStatement>(cond, body, ElseStatementList{});
|
|
||||||
|
|
||||||
EXPECT_EQ(str(stmt), R"(If{
|
EXPECT_EQ(str(stmt), R"(If{
|
||||||
(
|
(
|
||||||
|
@ -89,12 +119,10 @@ TEST_F(IfStatementTest, ToStr) {
|
||||||
|
|
||||||
TEST_F(IfStatementTest, ToStr_WithElseStatements) {
|
TEST_F(IfStatementTest, ToStr_WithElseStatements) {
|
||||||
auto* cond = Expr("cond");
|
auto* cond = Expr("cond");
|
||||||
auto* body =
|
auto* body = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
auto* else_if_body = Block(create<DiscardStatement>());
|
||||||
auto* else_if_body =
|
auto* else_body =
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
Block(create<DiscardStatement>(), create<DiscardStatement>());
|
||||||
auto* else_body = create<BlockStatement>(
|
|
||||||
StatementList{create<DiscardStatement>(), create<DiscardStatement>()});
|
|
||||||
auto* stmt = create<IfStatement>(
|
auto* stmt = create<IfStatement>(
|
||||||
cond, body,
|
cond, body,
|
||||||
ElseStatementList{
|
ElseStatementList{
|
||||||
|
|
|
@ -27,6 +27,8 @@ LoopStatement::LoopStatement(ProgramID program_id,
|
||||||
BlockStatement* continuing)
|
BlockStatement* continuing)
|
||||||
: Base(program_id, source), body_(body), continuing_(continuing) {
|
: Base(program_id, source), body_(body), continuing_(continuing) {
|
||||||
TINT_ASSERT(body_);
|
TINT_ASSERT(body_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(body_, program_id);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(continuing_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoopStatement::LoopStatement(LoopStatement&&) = default;
|
LoopStatement::LoopStatement(LoopStatement&&) = default;
|
||||||
|
|
|
@ -26,12 +26,10 @@ namespace {
|
||||||
using LoopStatementTest = TestHelper;
|
using LoopStatementTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, Creation) {
|
TEST_F(LoopStatementTest, Creation) {
|
||||||
auto* body =
|
auto* body = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
auto* b = body->last();
|
auto* b = body->last();
|
||||||
|
|
||||||
auto* continuing =
|
auto* continuing = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* l = create<LoopStatement>(body, continuing);
|
auto* l = create<LoopStatement>(body, continuing);
|
||||||
ASSERT_EQ(l->body()->size(), 1u);
|
ASSERT_EQ(l->body()->size(), 1u);
|
||||||
|
@ -41,11 +39,9 @@ TEST_F(LoopStatementTest, Creation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, Creation_WithSource) {
|
TEST_F(LoopStatementTest, Creation_WithSource) {
|
||||||
auto* body =
|
auto* body = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* continuing =
|
auto* continuing = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* l =
|
auto* l =
|
||||||
create<LoopStatement>(Source{Source::Location{20, 2}}, body, continuing);
|
create<LoopStatement>(Source{Source::Location{20, 2}}, body, continuing);
|
||||||
|
@ -55,31 +51,27 @@ TEST_F(LoopStatementTest, Creation_WithSource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, IsLoop) {
|
TEST_F(LoopStatementTest, IsLoop) {
|
||||||
auto* l = create<LoopStatement>(create<BlockStatement>(StatementList{}),
|
auto* l = create<LoopStatement>(Block(), Block());
|
||||||
create<BlockStatement>(StatementList{}));
|
|
||||||
EXPECT_TRUE(l->Is<LoopStatement>());
|
EXPECT_TRUE(l->Is<LoopStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) {
|
TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) {
|
||||||
auto* body =
|
auto* body = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* l = create<LoopStatement>(body, nullptr);
|
auto* l = create<LoopStatement>(body, nullptr);
|
||||||
EXPECT_FALSE(l->has_continuing());
|
EXPECT_FALSE(l->has_continuing());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, HasContinuing_WithContinuing) {
|
TEST_F(LoopStatementTest, HasContinuing_WithContinuing) {
|
||||||
auto* body =
|
auto* body = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* continuing =
|
auto* continuing = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* l = create<LoopStatement>(body, continuing);
|
auto* l = create<LoopStatement>(body, continuing);
|
||||||
EXPECT_TRUE(l->has_continuing());
|
EXPECT_TRUE(l->has_continuing());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, Assert_NullBody) {
|
TEST_F(LoopStatementTest, Assert_Null_Body) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -88,9 +80,28 @@ TEST_F(LoopStatementTest, Assert_NullBody) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(LoopStatementTest, Assert_DifferentProgramID_Body) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<LoopStatement>(b2.Block(), b1.Block());
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LoopStatementTest, Assert_DifferentProgramID_Continuing) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<LoopStatement>(b1.Block(), b2.Block());
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, ToStr) {
|
TEST_F(LoopStatementTest, ToStr) {
|
||||||
auto* body =
|
auto* body = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* l = create<LoopStatement>(body, nullptr);
|
auto* l = create<LoopStatement>(body, nullptr);
|
||||||
EXPECT_EQ(str(l), R"(Loop{
|
EXPECT_EQ(str(l), R"(Loop{
|
||||||
|
@ -100,11 +111,9 @@ TEST_F(LoopStatementTest, ToStr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LoopStatementTest, ToStr_WithContinuing) {
|
TEST_F(LoopStatementTest, ToStr_WithContinuing) {
|
||||||
auto* body =
|
auto* body = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* continuing =
|
auto* continuing = Block(create<DiscardStatement>());
|
||||||
create<BlockStatement>(StatementList{create<DiscardStatement>()});
|
|
||||||
|
|
||||||
auto* l = create<LoopStatement>(body, continuing);
|
auto* l = create<LoopStatement>(body, continuing);
|
||||||
EXPECT_EQ(str(l), R"(Loop{
|
EXPECT_EQ(str(l), R"(Loop{
|
||||||
|
|
|
@ -26,8 +26,10 @@ MemberAccessorExpression::MemberAccessorExpression(ProgramID program_id,
|
||||||
Expression* structure,
|
Expression* structure,
|
||||||
IdentifierExpression* member)
|
IdentifierExpression* member)
|
||||||
: Base(program_id, source), struct_(structure), member_(member) {
|
: Base(program_id, source), struct_(structure), member_(member) {
|
||||||
TINT_ASSERT(structure);
|
TINT_ASSERT(struct_);
|
||||||
TINT_ASSERT(member);
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(struct_, program_id);
|
||||||
|
TINT_ASSERT(member_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(member_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberAccessorExpression::MemberAccessorExpression(MemberAccessorExpression&&) =
|
MemberAccessorExpression::MemberAccessorExpression(MemberAccessorExpression&&) =
|
||||||
|
|
|
@ -44,7 +44,7 @@ TEST_F(MemberAccessorExpressionTest, IsMemberAccessor) {
|
||||||
EXPECT_TRUE(stmt->Is<MemberAccessorExpression>());
|
EXPECT_TRUE(stmt->Is<MemberAccessorExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MemberAccessorExpressionTest, Assert_NullStruct) {
|
TEST_F(MemberAccessorExpressionTest, Assert_Null_Struct) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -53,7 +53,7 @@ TEST_F(MemberAccessorExpressionTest, Assert_NullStruct) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MemberAccessorExpressionTest, Assert_NullMember) {
|
TEST_F(MemberAccessorExpressionTest, Assert_Null_Member) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -62,6 +62,28 @@ TEST_F(MemberAccessorExpressionTest, Assert_NullMember) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(MemberAccessorExpressionTest, Assert_DifferentProgramID_Struct) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<MemberAccessorExpression>(b2.Expr("structure"),
|
||||||
|
b1.Expr("member"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(MemberAccessorExpressionTest, Assert_DifferentProgramID_Member) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<MemberAccessorExpression>(b1.Expr("structure"),
|
||||||
|
b2.Expr("member"));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(MemberAccessorExpressionTest, ToStr) {
|
TEST_F(MemberAccessorExpressionTest, ToStr) {
|
||||||
auto* stmt =
|
auto* stmt =
|
||||||
create<MemberAccessorExpression>(Expr("structure"), Expr("member"));
|
create<MemberAccessorExpression>(Expr("structure"), Expr("member"));
|
||||||
|
|
|
@ -53,6 +53,7 @@ class Module : public Castable<Module, Node> {
|
||||||
/// @param var the variable to add
|
/// @param var the variable to add
|
||||||
void AddGlobalVariable(ast::Variable* var) {
|
void AddGlobalVariable(ast::Variable* var) {
|
||||||
TINT_ASSERT(var);
|
TINT_ASSERT(var);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(var, program_id());
|
||||||
global_variables_.push_back(var);
|
global_variables_.push_back(var);
|
||||||
global_declarations_.push_back(var);
|
global_declarations_.push_back(var);
|
||||||
}
|
}
|
||||||
|
@ -81,6 +82,7 @@ class Module : public Castable<Module, Node> {
|
||||||
/// @param func the function to add
|
/// @param func the function to add
|
||||||
void AddFunction(ast::Function* func) {
|
void AddFunction(ast::Function* func) {
|
||||||
TINT_ASSERT(func);
|
TINT_ASSERT(func);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(func, program_id());
|
||||||
functions_.push_back(func);
|
functions_.push_back(func);
|
||||||
global_declarations_.push_back(func);
|
global_declarations_.push_back(func);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,29 @@ TEST_F(ModuleTest, Assert_Null_ConstructedType) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ModuleTest, Assert_DifferentProgramID_Function) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.AST().AddFunction(b2.create<ast::Function>(
|
||||||
|
b2.Symbols().Register("func"), VariableList{}, b2.ty.f32(),
|
||||||
|
b2.Block(), DecorationList{}, DecorationList{}));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ModuleTest, Assert_DifferentProgramID_GlobalVariable) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.AST().AddGlobalVariable(
|
||||||
|
b2.Var("var", b2.ty.i32(), ast::StorageClass::kPrivate));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ModuleTest, Assert_Null_Function) {
|
TEST_F(ModuleTest, Assert_Null_Function) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,6 +78,13 @@ class Node : public Castable<Node, Cloneable> {
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
|
|
||||||
|
/// @param node a pointer to an AST node
|
||||||
|
/// @returns the ProgramID of the given AST node.
|
||||||
|
inline ProgramID ProgramIDOf(ast::Node* node) {
|
||||||
|
return node ? node->program_id() : ProgramID();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_AST_NODE_H_
|
#endif // SRC_AST_NODE_H_
|
||||||
|
|
|
@ -27,7 +27,9 @@ ReturnStatement::ReturnStatement(ProgramID program_id, const Source& source)
|
||||||
ReturnStatement::ReturnStatement(ProgramID program_id,
|
ReturnStatement::ReturnStatement(ProgramID program_id,
|
||||||
const Source& source,
|
const Source& source,
|
||||||
Expression* value)
|
Expression* value)
|
||||||
: Base(program_id, source), value_(value) {}
|
: Base(program_id, source), value_(value) {
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(value_, program_id);
|
||||||
|
}
|
||||||
|
|
||||||
ReturnStatement::ReturnStatement(ReturnStatement&&) = default;
|
ReturnStatement::ReturnStatement(ReturnStatement&&) = default;
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "src/ast/return_statement.h"
|
#include "src/ast/return_statement.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest-spi.h"
|
||||||
#include "src/ast/test_helper.h"
|
#include "src/ast/test_helper.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
@ -69,6 +70,16 @@ TEST_F(ReturnStatementTest, ToStr_WithoutValue) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ReturnStatementTest, Assert_DifferentProgramID_Expr) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<ReturnStatement>(b2.Expr(true));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -26,6 +26,7 @@ ScalarConstructorExpression::ScalarConstructorExpression(ProgramID program_id,
|
||||||
Literal* literal)
|
Literal* literal)
|
||||||
: Base(program_id, source), literal_(literal) {
|
: Base(program_id, source), literal_(literal) {
|
||||||
TINT_ASSERT(literal);
|
TINT_ASSERT(literal);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(literal, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScalarConstructorExpression::ScalarConstructorExpression(
|
ScalarConstructorExpression::ScalarConstructorExpression(
|
||||||
|
|
|
@ -40,6 +40,17 @@ TEST_F(ScalarConstructorExpressionTest, ToStr) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ScalarConstructorExpressionTest, Assert_DifferentProgramID_Literal) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<ScalarConstructorExpression>(
|
||||||
|
b2.create<BoolLiteral>(b2.ty.bool_(), true));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace ast
|
} // namespace ast
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -31,9 +31,11 @@ Struct::Struct(ProgramID program_id,
|
||||||
decorations_(std::move(decorations)) {
|
decorations_(std::move(decorations)) {
|
||||||
for (auto* mem : members_) {
|
for (auto* mem : members_) {
|
||||||
TINT_ASSERT(mem);
|
TINT_ASSERT(mem);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(mem, program_id);
|
||||||
}
|
}
|
||||||
for (auto* deco : decorations_) {
|
for (auto* deco : decorations_) {
|
||||||
TINT_ASSERT(deco);
|
TINT_ASSERT(deco);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(deco, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ StructMember::StructMember(ProgramID program_id,
|
||||||
TINT_ASSERT(symbol_.IsValid());
|
TINT_ASSERT(symbol_.IsValid());
|
||||||
for (auto* deco : decorations_) {
|
for (auto* deco : decorations_) {
|
||||||
TINT_ASSERT(deco);
|
TINT_ASSERT(deco);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(deco, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ TEST_F(StructMemberTest, CreationWithSource) {
|
||||||
EXPECT_EQ(st->source().range.end.column, 8u);
|
EXPECT_EQ(st->source().range.end.column, 8u);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StructMemberTest, Assert_EmptySymbol) {
|
TEST_F(StructMemberTest, Assert_Empty_Symbol) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -55,7 +55,7 @@ TEST_F(StructMemberTest, Assert_EmptySymbol) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StructMemberTest, Assert_NullType) {
|
TEST_F(StructMemberTest, Assert_Null_Type) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -64,7 +64,7 @@ TEST_F(StructMemberTest, Assert_NullType) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(StructMemberTest, Assert_NullDecoration) {
|
TEST_F(StructMemberTest, Assert_Null_Decoration) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -73,6 +73,16 @@ TEST_F(StructMemberTest, Assert_NullDecoration) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(StructMemberTest, Assert_DifferentProgramID_Decoration) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.Member("a", b1.ty.i32(), {b2.MemberSize(4)});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(StructMemberTest, ToStr) {
|
TEST_F(StructMemberTest, ToStr) {
|
||||||
auto* st = Member("a", ty.i32(), {MemberSize(4)});
|
auto* st = Member("a", ty.i32(), {MemberSize(4)});
|
||||||
EXPECT_EQ(str(st), "StructMember{[[ size 4 ]] a: __i32}\n");
|
EXPECT_EQ(str(st), "StructMember{[[ size 4 ]] a: __i32}\n");
|
||||||
|
|
|
@ -83,6 +83,28 @@ TEST_F(StructTest, Assert_Null_Decoration) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(StructTest, Assert_DifferentProgramID_StructMember) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<Struct>(StructMemberList{b2.Member("a", b2.ty.i32())},
|
||||||
|
DecorationList{});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(StructTest, Assert_DifferentProgramID_Decoration) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<Struct>(StructMemberList{b1.Member("a", b1.ty.i32())},
|
||||||
|
DecorationList{b2.create<StructBlockDecoration>()});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(StructTest, ToStr) {
|
TEST_F(StructTest, ToStr) {
|
||||||
DecorationList decos;
|
DecorationList decos;
|
||||||
decos.push_back(create<StructBlockDecoration>());
|
decos.push_back(create<StructBlockDecoration>());
|
||||||
|
|
|
@ -27,8 +27,10 @@ SwitchStatement::SwitchStatement(ProgramID program_id,
|
||||||
CaseStatementList body)
|
CaseStatementList body)
|
||||||
: Base(program_id, source), condition_(condition), body_(body) {
|
: Base(program_id, source), condition_(condition), body_(body) {
|
||||||
TINT_ASSERT(condition_);
|
TINT_ASSERT(condition_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(condition_, program_id);
|
||||||
for (auto* stmt : body_) {
|
for (auto* stmt : body_) {
|
||||||
TINT_ASSERT(stmt);
|
TINT_ASSERT(stmt);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(stmt, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@ TEST_F(SwitchStatementTest, Creation) {
|
||||||
|
|
||||||
auto* ident = Expr("ident");
|
auto* ident = Expr("ident");
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
auto* case_stmt =
|
auto* case_stmt = create<CaseStatement>(lit, Block());
|
||||||
create<CaseStatement>(lit, create<BlockStatement>(StatementList{}));
|
|
||||||
body.push_back(case_stmt);
|
body.push_back(case_stmt);
|
||||||
|
|
||||||
auto* stmt = create<SwitchStatement>(ident, body);
|
auto* stmt = create<SwitchStatement>(ident, body);
|
||||||
|
@ -55,8 +54,7 @@ TEST_F(SwitchStatementTest, IsSwitch) {
|
||||||
|
|
||||||
auto* ident = Expr("ident");
|
auto* ident = Expr("ident");
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
body.push_back(
|
body.push_back(create<CaseStatement>(lit, Block()));
|
||||||
create<CaseStatement>(lit, create<BlockStatement>(StatementList{})));
|
|
||||||
|
|
||||||
auto* stmt = create<SwitchStatement>(ident, body);
|
auto* stmt = create<SwitchStatement>(ident, body);
|
||||||
EXPECT_TRUE(stmt->Is<SwitchStatement>());
|
EXPECT_TRUE(stmt->Is<SwitchStatement>());
|
||||||
|
@ -68,8 +66,7 @@ TEST_F(SwitchStatementTest, Assert_Null_Condition) {
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
CaseStatementList cases;
|
CaseStatementList cases;
|
||||||
cases.push_back(
|
cases.push_back(
|
||||||
b.create<CaseStatement>(CaseSelectorList{b.Literal(1)},
|
b.create<CaseStatement>(CaseSelectorList{b.Literal(1)}, b.Block()));
|
||||||
b.create<BlockStatement>(StatementList{})));
|
|
||||||
b.create<SwitchStatement>(nullptr, cases);
|
b.create<SwitchStatement>(nullptr, cases);
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
|
@ -84,6 +81,38 @@ TEST_F(SwitchStatementTest, Assert_Null_CaseStatement) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SwitchStatementTest, Assert_DifferentProgramID_Condition) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<SwitchStatement>(b2.Expr(true), CaseStatementList{
|
||||||
|
b1.create<CaseStatement>(
|
||||||
|
CaseSelectorList{
|
||||||
|
b1.Literal(1),
|
||||||
|
},
|
||||||
|
b1.Block()),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SwitchStatementTest, Assert_DifferentProgramID_CaseStatement) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<SwitchStatement>(b1.Expr(true), CaseStatementList{
|
||||||
|
b2.create<CaseStatement>(
|
||||||
|
CaseSelectorList{
|
||||||
|
b2.Literal(1),
|
||||||
|
},
|
||||||
|
b2.Block()),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SwitchStatementTest, ToStr_Empty) {
|
TEST_F(SwitchStatementTest, ToStr_Empty) {
|
||||||
auto* ident = Expr("ident");
|
auto* ident = Expr("ident");
|
||||||
|
|
||||||
|
@ -102,8 +131,7 @@ TEST_F(SwitchStatementTest, ToStr) {
|
||||||
|
|
||||||
auto* ident = Expr("ident");
|
auto* ident = Expr("ident");
|
||||||
CaseStatementList body;
|
CaseStatementList body;
|
||||||
body.push_back(
|
body.push_back(create<CaseStatement>(lit, Block()));
|
||||||
create<CaseStatement>(lit, create<BlockStatement>(StatementList{})));
|
|
||||||
|
|
||||||
auto* stmt = create<SwitchStatement>(ident, body);
|
auto* stmt = create<SwitchStatement>(ident, body);
|
||||||
EXPECT_EQ(str(stmt), R"(Switch{
|
EXPECT_EQ(str(stmt), R"(Switch{
|
||||||
|
|
|
@ -26,9 +26,10 @@ TypeConstructorExpression::TypeConstructorExpression(ProgramID program_id,
|
||||||
type::Type* type,
|
type::Type* type,
|
||||||
ExpressionList values)
|
ExpressionList values)
|
||||||
: Base(program_id, source), type_(type), values_(std::move(values)) {
|
: Base(program_id, source), type_(type), values_(std::move(values)) {
|
||||||
TINT_ASSERT(type);
|
TINT_ASSERT(type_);
|
||||||
for (auto* val : values_) {
|
for (auto* val : values_) {
|
||||||
TINT_ASSERT(val);
|
TINT_ASSERT(val);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(val, program_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ TEST_F(TypeConstructorExpressionTest, IsTypeConstructor) {
|
||||||
EXPECT_TRUE(t->Is<TypeConstructorExpression>());
|
EXPECT_TRUE(t->Is<TypeConstructorExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TypeConstructorExpressionTest, Assert_NullType) {
|
TEST_F(TypeConstructorExpressionTest, Assert_Null_Type) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -59,7 +59,7 @@ TEST_F(TypeConstructorExpressionTest, Assert_NullType) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TypeConstructorExpressionTest, Assert_NullValue) {
|
TEST_F(TypeConstructorExpressionTest, Assert_Null_Value) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -69,6 +69,17 @@ TEST_F(TypeConstructorExpressionTest, Assert_NullValue) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TypeConstructorExpressionTest, Assert_DifferentProgramID_Value) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<TypeConstructorExpression>(b1.ty.i32(),
|
||||||
|
ExpressionList{b2.Expr(1)});
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(TypeConstructorExpressionTest, ToStr) {
|
TEST_F(TypeConstructorExpressionTest, ToStr) {
|
||||||
type::Vector vec(ty.f32(), 3);
|
type::Vector vec(ty.f32(), 3);
|
||||||
ExpressionList expr;
|
ExpressionList expr;
|
||||||
|
|
|
@ -27,6 +27,7 @@ UnaryOpExpression::UnaryOpExpression(ProgramID program_id,
|
||||||
Expression* expr)
|
Expression* expr)
|
||||||
: Base(program_id, source), op_(op), expr_(expr) {
|
: Base(program_id, source), op_(op), expr_(expr) {
|
||||||
TINT_ASSERT(expr_);
|
TINT_ASSERT(expr_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(expr_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default;
|
UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default;
|
||||||
|
|
|
@ -46,7 +46,7 @@ TEST_F(UnaryOpExpressionTest, IsUnaryOp) {
|
||||||
EXPECT_TRUE(u->Is<UnaryOpExpression>());
|
EXPECT_TRUE(u->Is<UnaryOpExpression>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UnaryOpExpressionTest, Assert_NullExpression) {
|
TEST_F(UnaryOpExpressionTest, Assert_Null_Expression) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -55,6 +55,16 @@ TEST_F(UnaryOpExpressionTest, Assert_NullExpression) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(UnaryOpExpressionTest, Assert_DifferentProgramID_Expression) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<UnaryOpExpression>(UnaryOp::kNot, b2.Expr(true));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(UnaryOpExpressionTest, ToStr) {
|
TEST_F(UnaryOpExpressionTest, ToStr) {
|
||||||
auto* ident = Expr("ident");
|
auto* ident = Expr("ident");
|
||||||
auto* u = create<UnaryOpExpression>(UnaryOp::kNot, ident);
|
auto* u = create<UnaryOpExpression>(UnaryOp::kNot, ident);
|
||||||
|
|
|
@ -41,6 +41,7 @@ Variable::Variable(ProgramID program_id,
|
||||||
TINT_ASSERT(symbol_.IsValid());
|
TINT_ASSERT(symbol_.IsValid());
|
||||||
// no type means we must have a constructor to infer it
|
// no type means we must have a constructor to infer it
|
||||||
TINT_ASSERT(declared_type_ || constructor);
|
TINT_ASSERT(declared_type_ || constructor);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(constructor, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable::Variable(Variable&&) = default;
|
Variable::Variable(Variable&&) = default;
|
||||||
|
|
|
@ -26,6 +26,7 @@ VariableDeclStatement::VariableDeclStatement(ProgramID program_id,
|
||||||
Variable* variable)
|
Variable* variable)
|
||||||
: Base(program_id, source), variable_(variable) {
|
: Base(program_id, source), variable_(variable) {
|
||||||
TINT_ASSERT(variable_);
|
TINT_ASSERT(variable_);
|
||||||
|
TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(variable_, program_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default;
|
VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default;
|
||||||
|
|
|
@ -47,7 +47,7 @@ TEST_F(VariableDeclStatementTest, IsVariableDecl) {
|
||||||
EXPECT_TRUE(stmt->Is<VariableDeclStatement>());
|
EXPECT_TRUE(stmt->Is<VariableDeclStatement>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, Assert_NullVariable) {
|
TEST_F(VariableDeclStatementTest, Assert_Null_Variable) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -56,6 +56,17 @@ TEST_F(VariableDeclStatementTest, Assert_NullVariable) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(VariableDeclStatementTest, Assert_DifferentProgramID_Variable) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.create<VariableDeclStatement>(
|
||||||
|
b2.Var("a", b2.ty.f32(), StorageClass::kNone));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(VariableDeclStatementTest, ToStr) {
|
TEST_F(VariableDeclStatementTest, ToStr) {
|
||||||
auto* var = Var("a", ty.f32(), StorageClass::kNone);
|
auto* var = Var("a", ty.f32(), StorageClass::kNone);
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ TEST_F(VariableTest, Assert_MissingSymbol) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, Assert_NullType) {
|
TEST_F(VariableTest, Assert_Null_Type) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
|
@ -80,6 +80,16 @@ TEST_F(VariableTest, Assert_NullType) {
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(VariableTest, Assert_DifferentProgramID_Constructor) {
|
||||||
|
EXPECT_FATAL_FAILURE(
|
||||||
|
{
|
||||||
|
ProgramBuilder b1;
|
||||||
|
ProgramBuilder b2;
|
||||||
|
b1.Var("x", b1.ty.f32(), StorageClass::kNone, b2.Expr(1.2f));
|
||||||
|
},
|
||||||
|
"internal compiler error");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, to_str) {
|
TEST_F(VariableTest, to_str) {
|
||||||
auto* v = Var("my_var", ty.f32(), StorageClass::kFunction);
|
auto* v = Var("my_var", ty.f32(), StorageClass::kFunction);
|
||||||
EXPECT_EQ(str(v), R"(Variable{
|
EXPECT_EQ(str(v), R"(Variable{
|
||||||
|
|
|
@ -16,9 +16,19 @@
|
||||||
#define SRC_PROGRAM_ID_H_
|
#define SRC_PROGRAM_ID_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "src/debug.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
|
|
||||||
|
/// If 1 then checks are enabled that AST nodes are not leaked from one program
|
||||||
|
/// to another.
|
||||||
|
/// TODO(bclayton): We'll want to disable this in production builds. For now we
|
||||||
|
/// always check.
|
||||||
|
#define TINT_CHECK_FOR_CROSS_PROGRAM_LEAKS 1
|
||||||
|
|
||||||
/// A ProgramID is a unique identifier of a Program.
|
/// A ProgramID is a unique identifier of a Program.
|
||||||
/// ProgramID can be used to ensure that objects referenced by the Program are
|
/// ProgramID can be used to ensure that objects referenced by the Program are
|
||||||
/// owned exclusively by that Program and have accidentally not leaked from
|
/// owned exclusively by that Program and have accidentally not leaked from
|
||||||
|
@ -28,7 +38,7 @@ class ProgramID {
|
||||||
/// Constructor
|
/// Constructor
|
||||||
ProgramID();
|
ProgramID();
|
||||||
|
|
||||||
/// @returns a new ProgramID
|
/// @returns a new. globally unique ProgramID
|
||||||
static ProgramID New();
|
static ProgramID New();
|
||||||
|
|
||||||
/// Equality operator
|
/// Equality operator
|
||||||
|
@ -41,12 +51,85 @@ class ProgramID {
|
||||||
/// @returns true if the ProgramIDs are not equal
|
/// @returns true if the ProgramIDs are not equal
|
||||||
bool operator!=(const ProgramID& rhs) const { return val != rhs.val; }
|
bool operator!=(const ProgramID& rhs) const { return val != rhs.val; }
|
||||||
|
|
||||||
|
/// @returns the numerical identifier value
|
||||||
|
uint32_t Value() const { return val; }
|
||||||
|
|
||||||
|
/// @returns true if this ProgramID is valid
|
||||||
|
operator bool() const { return val != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ProgramID(uint32_t);
|
explicit ProgramID(uint32_t);
|
||||||
|
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A simple pass-through function for ProgramID. Intended to be overloaded for
|
||||||
|
/// other types.
|
||||||
|
/// @param id a ProgramID
|
||||||
|
/// @returns id. Simple pass-through function
|
||||||
|
inline ProgramID ProgramIDOf(ProgramID id) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes the ProgramID to the std::ostream.
|
||||||
|
/// @param out the std::ostream to write to
|
||||||
|
/// @param id the program identifier to write
|
||||||
|
/// @returns out so calls can be chained
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, ProgramID id) {
|
||||||
|
out << "Program<" << id.Value() << ">";
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
/// AssertProgramIDsEqual is called by TINT_ASSERT_PROGRAM_IDS_EQUAL() and
|
||||||
|
/// TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID() to assert that the ProgramIDs of
|
||||||
|
/// `a` and `b` are equal.
|
||||||
|
template <typename A, typename B>
|
||||||
|
void AssertProgramIDsEqual(A&& a,
|
||||||
|
B&& b,
|
||||||
|
bool if_valid,
|
||||||
|
const char* msg,
|
||||||
|
const char* file,
|
||||||
|
size_t line) {
|
||||||
|
auto a_id = ProgramIDOf(std::forward<A>(a));
|
||||||
|
auto b_id = ProgramIDOf(std::forward<B>(b));
|
||||||
|
if (a_id == b_id) {
|
||||||
|
return; // matched
|
||||||
|
}
|
||||||
|
if (if_valid && (!a_id || !b_id)) {
|
||||||
|
return; // a or b were not valid
|
||||||
|
}
|
||||||
|
diag::List diagnostics;
|
||||||
|
tint::InternalCompilerError(file, line, diagnostics) << msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// TINT_ASSERT_PROGRAM_IDS_EQUAL(A, B) is a macro that asserts that the program
|
||||||
|
/// identifiers for A and B are equal.
|
||||||
|
///
|
||||||
|
/// TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(A, B) is a macro that asserts that
|
||||||
|
/// the program identifiers for A and B are equal, if both A and B have valid
|
||||||
|
/// program identifiers.
|
||||||
|
#if TINT_CHECK_FOR_CROSS_PROGRAM_LEAKS
|
||||||
|
#define TINT_ASSERT_PROGRAM_IDS_EQUAL(a, b) \
|
||||||
|
detail::AssertProgramIDsEqual( \
|
||||||
|
a, b, false, "TINT_ASSERT_PROGRAM_IDS_EQUAL(" #a ", " #b ")", __FILE__, \
|
||||||
|
__LINE__)
|
||||||
|
#define TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(a, b) \
|
||||||
|
detail::AssertProgramIDsEqual( \
|
||||||
|
a, b, true, "TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(" #a ", " #b ")", \
|
||||||
|
__FILE__, __LINE__)
|
||||||
|
#else
|
||||||
|
#define TINT_ASSERT_PROGRAM_IDS_EQUAL(a, b) \
|
||||||
|
do { \
|
||||||
|
} while (false)
|
||||||
|
#define TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(a, b) \
|
||||||
|
do { \
|
||||||
|
} while (false)
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
||||||
#endif // SRC_PROGRAM_ID_H_
|
#endif // SRC_PROGRAM_ID_H_
|
||||||
|
|
Loading…
Reference in New Issue