diff --git a/src/ast/array_accessor_expression.cc b/src/ast/array_accessor_expression.cc index 934055ec1d..5424a98cc4 100644 --- a/src/ast/array_accessor_expression.cc +++ b/src/ast/array_accessor_expression.cc @@ -24,7 +24,10 @@ namespace ast { ArrayAccessorExpression::ArrayAccessorExpression(const Source& source, Expression* array, Expression* idx_expr) - : Base(source), array_(array), idx_expr_(idx_expr) {} + : Base(source), array_(array), idx_expr_(idx_expr) { + TINT_ASSERT(array_); + TINT_ASSERT(idx_expr_); +} ArrayAccessorExpression::ArrayAccessorExpression(ArrayAccessorExpression&&) = default; @@ -40,15 +43,6 @@ ArrayAccessorExpression* ArrayAccessorExpression::Clone( return ctx->dst->create(src, arr, idx); } -bool ArrayAccessorExpression::IsValid() const { - if (array_ == nullptr || !array_->IsValid()) - return false; - if (idx_expr_ == nullptr || !idx_expr_->IsValid()) - return false; - - return true; -} - void ArrayAccessorExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/array_accessor_expression.h b/src/ast/array_accessor_expression.h index f6e8f1e17c..24a13ec2a2 100644 --- a/src/ast/array_accessor_expression.h +++ b/src/ast/array_accessor_expression.h @@ -47,9 +47,6 @@ class ArrayAccessorExpression /// @return the newly cloned node ArrayAccessorExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/array_accessor_expression_test.cc b/src/ast/array_accessor_expression_test.cc index 671ec988c5..154cc6994b 100644 --- a/src/ast/array_accessor_expression_test.cc +++ b/src/ast/array_accessor_expression_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -48,40 +49,22 @@ TEST_F(ArrayAccessorExpressionTest, IsArrayAccessor) { EXPECT_TRUE(exp->Is()); } -TEST_F(ArrayAccessorExpressionTest, IsValid) { - auto* ary = Expr("ary"); - auto* idx = Expr("idx"); - - auto* exp = create(ary, idx); - EXPECT_TRUE(exp->IsValid()); +TEST_F(ArrayAccessorExpressionTest, Assert_NullArray) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr, b.Expr("idx")); + }, + "internal compiler error"); } -TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) { - auto* idx = Expr("idx"); - - auto* exp = create(nullptr, idx); - EXPECT_FALSE(exp->IsValid()); -} - -TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) { - auto* ary = Expr("ary"); - - auto* exp = create(ary, nullptr); - EXPECT_FALSE(exp->IsValid()); -} - -TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidArray) { - auto* ary = Expr(""); - auto* idx = Expr("idx"); - auto* exp = create(ary, idx); - EXPECT_FALSE(exp->IsValid()); -} - -TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidIndex) { - auto* ary = Expr("ary"); - auto* idx = Expr(""); - auto* exp = create(ary, idx); - EXPECT_FALSE(exp->IsValid()); +TEST_F(ArrayAccessorExpressionTest, Assert_NullIndex) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.Expr("arr"), nullptr); + }, + "internal compiler error"); } TEST_F(ArrayAccessorExpressionTest, ToStr) { diff --git a/src/ast/assignment_statement.cc b/src/ast/assignment_statement.cc index 3230499b97..8e98c23302 100644 --- a/src/ast/assignment_statement.cc +++ b/src/ast/assignment_statement.cc @@ -24,7 +24,10 @@ namespace ast { AssignmentStatement::AssignmentStatement(const Source& source, Expression* lhs, Expression* rhs) - : Base(source), lhs_(lhs), rhs_(rhs) {} + : Base(source), lhs_(lhs), rhs_(rhs) { + TINT_ASSERT(lhs_); + TINT_ASSERT(rhs_); +} AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default; @@ -38,15 +41,6 @@ AssignmentStatement* AssignmentStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, l, r); } -bool AssignmentStatement::IsValid() const { - if (lhs_ == nullptr || !lhs_->IsValid()) - return false; - if (rhs_ == nullptr || !rhs_->IsValid()) - return false; - - return true; -} - void AssignmentStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/assignment_statement.h b/src/ast/assignment_statement.h index 4368ee7771..a7a0365072 100644 --- a/src/ast/assignment_statement.h +++ b/src/ast/assignment_statement.h @@ -44,9 +44,6 @@ class AssignmentStatement : public Castable { /// @return the newly cloned node AssignmentStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/assignment_statement_test.cc b/src/ast/assignment_statement_test.cc index 3a0234f90d..9ac7882f83 100644 --- a/src/ast/assignment_statement_test.cc +++ b/src/ast/assignment_statement_test.cc @@ -14,6 +14,7 @@ #include "src/ast/assignment_statement.h" +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -50,40 +51,22 @@ TEST_F(AssignmentStatementTest, IsAssign) { EXPECT_TRUE(stmt->Is()); } -TEST_F(AssignmentStatementTest, IsValid) { - auto* lhs = Expr("lhs"); - auto* rhs = Expr("rhs"); - - auto* stmt = create(lhs, rhs); - EXPECT_TRUE(stmt->IsValid()); +TEST_F(AssignmentStatementTest, Assert_NullLHS) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr, b.Expr(1)); + }, + "internal compiler error"); } -TEST_F(AssignmentStatementTest, IsValid_MissingLHS) { - auto* rhs = Expr("rhs"); - - auto* stmt = create(nullptr, rhs); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(AssignmentStatementTest, IsValid_MissingRHS) { - auto* lhs = Expr("lhs"); - - auto* stmt = create(lhs, nullptr); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(AssignmentStatementTest, IsValid_InvalidLHS) { - auto* lhs = Expr(""); - auto* rhs = Expr("rhs"); - auto* stmt = create(lhs, rhs); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(AssignmentStatementTest, IsValid_InvalidRHS) { - auto* lhs = Expr("lhs"); - auto* rhs = Expr(""); - auto* stmt = create(lhs, rhs); - EXPECT_FALSE(stmt->IsValid()); +TEST_F(AssignmentStatementTest, Assert_NullRHS) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.Expr(1), nullptr); + }, + "internal compiler error"); } TEST_F(AssignmentStatementTest, ToStr) { diff --git a/src/ast/binary_expression.cc b/src/ast/binary_expression.cc index 83fbaac7fb..2426eb9436 100644 --- a/src/ast/binary_expression.cc +++ b/src/ast/binary_expression.cc @@ -25,7 +25,11 @@ BinaryExpression::BinaryExpression(const Source& source, BinaryOp op, Expression* lhs, Expression* rhs) - : Base(source), op_(op), lhs_(lhs), rhs_(rhs) {} + : Base(source), op_(op), lhs_(lhs), rhs_(rhs) { + TINT_ASSERT(lhs_); + TINT_ASSERT(rhs_); + TINT_ASSERT(op_ != BinaryOp::kNone); +} BinaryExpression::BinaryExpression(BinaryExpression&&) = default; @@ -39,16 +43,6 @@ BinaryExpression* BinaryExpression::Clone(CloneContext* ctx) const { return ctx->dst->create(src, op_, l, r); } -bool BinaryExpression::IsValid() const { - if (lhs_ == nullptr || !lhs_->IsValid()) { - return false; - } - if (rhs_ == nullptr || !rhs_->IsValid()) { - return false; - } - return op_ != BinaryOp::kNone; -} - void BinaryExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/binary_expression.h b/src/ast/binary_expression.h index 036eb5a413..84834acaf1 100644 --- a/src/ast/binary_expression.h +++ b/src/ast/binary_expression.h @@ -110,9 +110,6 @@ class BinaryExpression : public Castable { /// @return the newly cloned node BinaryExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/binary_expression_test.cc b/src/ast/binary_expression_test.cc index 045231ecc9..8109e417c8 100644 --- a/src/ast/binary_expression_test.cc +++ b/src/ast/binary_expression_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -49,50 +50,22 @@ TEST_F(BinaryExpressionTest, IsBinary) { EXPECT_TRUE(r->Is()); } -TEST_F(BinaryExpressionTest, IsValid) { - auto* lhs = Expr("lhs"); - auto* rhs = Expr("rhs"); - - auto* r = create(BinaryOp::kEqual, lhs, rhs); - EXPECT_TRUE(r->IsValid()); -} - TEST_F(BinaryExpressionTest, IsValid_Null_LHS) { - auto* rhs = Expr("rhs"); - - auto* r = create(BinaryOp::kEqual, nullptr, rhs); - EXPECT_FALSE(r->IsValid()); -} - -TEST_F(BinaryExpressionTest, IsValid_Invalid_LHS) { - auto* lhs = Expr(""); - auto* rhs = Expr("rhs"); - - auto* r = create(BinaryOp::kEqual, lhs, rhs); - EXPECT_FALSE(r->IsValid()); + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(BinaryOp::kEqual, nullptr, b.Expr("rhs")); + }, + "internal compiler error"); } TEST_F(BinaryExpressionTest, IsValid_Null_RHS) { - auto* lhs = Expr("lhs"); - - auto* r = create(BinaryOp::kEqual, lhs, nullptr); - EXPECT_FALSE(r->IsValid()); -} - -TEST_F(BinaryExpressionTest, IsValid_Invalid_RHS) { - auto* lhs = Expr("lhs"); - auto* rhs = Expr(""); - - auto* r = create(BinaryOp::kEqual, lhs, rhs); - EXPECT_FALSE(r->IsValid()); -} - -TEST_F(BinaryExpressionTest, IsValid_Binary_None) { - auto* lhs = Expr("lhs"); - auto* rhs = Expr("rhs"); - - auto* r = create(BinaryOp::kNone, lhs, rhs); - EXPECT_FALSE(r->IsValid()); + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(BinaryOp::kEqual, b.Expr("lhs"), nullptr); + }, + "internal compiler error"); } TEST_F(BinaryExpressionTest, ToStr) { diff --git a/src/ast/bitcast_expression.cc b/src/ast/bitcast_expression.cc index 2b985f7c09..9d73fe420d 100644 --- a/src/ast/bitcast_expression.cc +++ b/src/ast/bitcast_expression.cc @@ -24,7 +24,10 @@ namespace ast { BitcastExpression::BitcastExpression(const Source& source, type::Type* type, Expression* expr) - : Base(source), type_(type), expr_(expr) {} + : Base(source), type_(type), expr_(expr) { + TINT_ASSERT(type_); + TINT_ASSERT(expr_); +} BitcastExpression::BitcastExpression(BitcastExpression&&) = default; BitcastExpression::~BitcastExpression() = default; @@ -37,12 +40,6 @@ BitcastExpression* BitcastExpression::Clone(CloneContext* ctx) const { return ctx->dst->create(src, ty, e); } -bool BitcastExpression::IsValid() const { - if (expr_ == nullptr || !expr_->IsValid()) - return false; - return type_ != nullptr; -} - void BitcastExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/bitcast_expression.h b/src/ast/bitcast_expression.h index d56dec8942..0e83b9190e 100644 --- a/src/ast/bitcast_expression.h +++ b/src/ast/bitcast_expression.h @@ -43,9 +43,6 @@ class BitcastExpression : public Castable { /// @return the newly cloned node BitcastExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/bitcast_expression_test.cc b/src/ast/bitcast_expression_test.cc index 3f2cc7c00e..754fa36f68 100644 --- a/src/ast/bitcast_expression_test.cc +++ b/src/ast/bitcast_expression_test.cc @@ -14,6 +14,7 @@ #include "src/ast/bitcast_expression.h" +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -47,29 +48,22 @@ TEST_F(BitcastExpressionTest, IsBitcast) { EXPECT_TRUE(exp->Is()); } -TEST_F(BitcastExpressionTest, IsValid) { - auto* expr = Expr("expr"); - - auto* exp = create(ty.f32(), expr); - EXPECT_TRUE(exp->IsValid()); +TEST_F(BitcastExpressionTest, Assert_NullType) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr, b.Expr("idx")); + }, + "internal compiler error"); } -TEST_F(BitcastExpressionTest, IsValid_MissingType) { - auto* expr = Expr("expr"); - - auto* exp = create(nullptr, expr); - EXPECT_FALSE(exp->IsValid()); -} - -TEST_F(BitcastExpressionTest, IsValid_MissingExpr) { - auto* exp = create(ty.f32(), nullptr); - EXPECT_FALSE(exp->IsValid()); -} - -TEST_F(BitcastExpressionTest, IsValid_InvalidExpr) { - auto* expr = Expr(""); - auto* e = create(ty.f32(), expr); - EXPECT_FALSE(e->IsValid()); +TEST_F(BitcastExpressionTest, Assert_NullExpr) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.ty.f32(), nullptr); + }, + "internal compiler error"); } TEST_F(BitcastExpressionTest, ToStr) { diff --git a/src/ast/block_statement.cc b/src/ast/block_statement.cc index 5ed4d04ba7..d2cdd936c1 100644 --- a/src/ast/block_statement.cc +++ b/src/ast/block_statement.cc @@ -23,7 +23,11 @@ namespace ast { BlockStatement::BlockStatement(const Source& source, const StatementList& statements) - : Base(source), statements_(std::move(statements)) {} + : Base(source), statements_(std::move(statements)) { + for (auto* stmt : *this) { + TINT_ASSERT(stmt); + } +} BlockStatement::BlockStatement(BlockStatement&&) = default; @@ -36,15 +40,6 @@ BlockStatement* BlockStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, stmts); } -bool BlockStatement::IsValid() const { - for (auto* stmt : *this) { - if (stmt == nullptr || !stmt->IsValid()) { - return false; - } - } - return true; -} - void BlockStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/block_statement.h b/src/ast/block_statement.h index f5653f955c..103c8c44ea 100644 --- a/src/ast/block_statement.h +++ b/src/ast/block_statement.h @@ -71,9 +71,6 @@ class BlockStatement : public Castable { /// @return the newly cloned node BlockStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/block_statement_test.cc b/src/ast/block_statement_test.cc index c4a583cc01..4a5b2dd591 100644 --- a/src/ast/block_statement_test.cc +++ b/src/ast/block_statement_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/discard_statement.h" #include "src/ast/if_statement.h" #include "src/ast/test_helper.h" @@ -45,35 +46,13 @@ TEST_F(BlockStatementTest, IsBlock) { EXPECT_TRUE(b->Is()); } -TEST_F(BlockStatementTest, IsValid) { - auto* b = create(ast::StatementList{ - create(), - }); - EXPECT_TRUE(b->IsValid()); -} - -TEST_F(BlockStatementTest, IsValid_Empty) { - auto* b = create(ast::StatementList{}); - EXPECT_TRUE(b->IsValid()); -} - -TEST_F(BlockStatementTest, IsValid_NullBodyStatement) { - auto* b = create(ast::StatementList{ - create(), - nullptr, - }); - - EXPECT_FALSE(b->IsValid()); -} - -TEST_F(BlockStatementTest, IsValid_InvalidBodyStatement) { - auto* b = create( - - ast::StatementList{ - create(nullptr, create(StatementList{}), - ElseStatementList{}), - }); - EXPECT_FALSE(b->IsValid()); +TEST_F(BlockStatementTest, Assert_NullStatement) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(ast::StatementList{nullptr}); + }, + "internal compiler error"); } TEST_F(BlockStatementTest, ToStr) { diff --git a/src/ast/break_statement.cc b/src/ast/break_statement.cc index 9ec4e347ed..0824c669dc 100644 --- a/src/ast/break_statement.cc +++ b/src/ast/break_statement.cc @@ -33,10 +33,6 @@ BreakStatement* BreakStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src); } -bool BreakStatement::IsValid() const { - return true; -} - void BreakStatement::to_str(const semantic::Info&, std::ostream& out, size_t indent) const { diff --git a/src/ast/break_statement.h b/src/ast/break_statement.h index 271b1ff418..1bc6148c4d 100644 --- a/src/ast/break_statement.h +++ b/src/ast/break_statement.h @@ -36,9 +36,6 @@ class BreakStatement : public Castable { /// @return the newly cloned node BreakStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/break_statement_test.cc b/src/ast/break_statement_test.cc index 78a0cf8ff6..236f151c66 100644 --- a/src/ast/break_statement_test.cc +++ b/src/ast/break_statement_test.cc @@ -34,11 +34,6 @@ TEST_F(BreakStatementTest, IsBreak) { EXPECT_TRUE(stmt->Is()); } -TEST_F(BreakStatementTest, IsValid) { - auto* stmt = create(); - EXPECT_TRUE(stmt->IsValid()); -} - TEST_F(BreakStatementTest, ToStr) { auto* stmt = create(); EXPECT_EQ(str(stmt), R"(Break{} diff --git a/src/ast/call_expression.cc b/src/ast/call_expression.cc index 628dae64b0..e58396bced 100644 --- a/src/ast/call_expression.cc +++ b/src/ast/call_expression.cc @@ -24,7 +24,12 @@ namespace ast { CallExpression::CallExpression(const Source& source, Expression* func, ExpressionList params) - : Base(source), func_(func), params_(params) {} + : Base(source), func_(func), params_(params) { + TINT_ASSERT(func_); + for (auto* param : params_) { + TINT_ASSERT(param); + } +} CallExpression::CallExpression(CallExpression&&) = default; @@ -38,18 +43,6 @@ CallExpression* CallExpression::Clone(CloneContext* ctx) const { return ctx->dst->create(src, fn, p); } -bool CallExpression::IsValid() const { - if (func_ == nullptr || !func_->IsValid()) - return false; - - // All params must be valid - for (auto* param : params_) { - if (param == nullptr || !param->IsValid()) - return false; - } - return true; -} - void CallExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/call_expression.h b/src/ast/call_expression.h index b503d036d0..f317a60b07 100644 --- a/src/ast/call_expression.h +++ b/src/ast/call_expression.h @@ -43,9 +43,6 @@ class CallExpression : public Castable { /// @return the newly cloned node CallExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/call_expression_test.cc b/src/ast/call_expression_test.cc index e02d6bb7c4..40401537b0 100644 --- a/src/ast/call_expression_test.cc +++ b/src/ast/call_expression_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -50,44 +51,26 @@ TEST_F(CallExpressionTest, IsCall) { EXPECT_TRUE(stmt->Is()); } -TEST_F(CallExpressionTest, IsValid) { - auto* func = Expr("func"); - auto* stmt = create(func, ExpressionList{}); - EXPECT_TRUE(stmt->IsValid()); +TEST_F(CallExpressionTest, Assert_NullFunction) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr, ExpressionList{}); + }, + "internal compiler error"); } -TEST_F(CallExpressionTest, IsValid_MissingFunction) { - auto* stmt = create(nullptr, ExpressionList{}); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(CallExpressionTest, IsValid_NullParam) { - auto* func = Expr("func"); - ExpressionList params; - params.push_back(Expr("param1")); - params.push_back(nullptr); - params.push_back(Expr("param2")); - - auto* stmt = create(func, params); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(CallExpressionTest, IsValid_InvalidFunction) { - auto* func = Expr(""); - ExpressionList params; - params.push_back(Expr("param1")); - - auto* stmt = create(func, params); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(CallExpressionTest, IsValid_InvalidParam) { - auto* func = Expr("func"); - ExpressionList params; - params.push_back(Expr("")); - - auto* stmt = create(func, params); - EXPECT_FALSE(stmt->IsValid()); +TEST_F(CallExpressionTest, Assert_NullParam) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + ExpressionList params; + params.push_back(b.Expr("param1")); + params.push_back(nullptr); + params.push_back(b.Expr("param2")); + b.create(b.Expr("func"), params); + }, + "internal compiler error"); } TEST_F(CallExpressionTest, ToStr_NoParams) { diff --git a/src/ast/call_statement.cc b/src/ast/call_statement.cc index 16ecfb127f..5b52a441b5 100644 --- a/src/ast/call_statement.cc +++ b/src/ast/call_statement.cc @@ -22,7 +22,9 @@ namespace tint { namespace ast { CallStatement::CallStatement(const Source& source, CallExpression* call) - : Base(source), call_(call) {} + : Base(source), call_(call) { + TINT_ASSERT(call_); +} CallStatement::CallStatement(CallStatement&&) = default; @@ -35,10 +37,6 @@ CallStatement* CallStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, call); } -bool CallStatement::IsValid() const { - return call_ != nullptr && call_->IsValid(); -} - void CallStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/call_statement.h b/src/ast/call_statement.h index dd2c837622..5c948a8b15 100644 --- a/src/ast/call_statement.h +++ b/src/ast/call_statement.h @@ -41,9 +41,6 @@ class CallStatement : public Castable { /// @return the newly cloned node CallStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/call_statement_test.cc b/src/ast/call_statement_test.cc index 2736463cc1..092dc541e7 100644 --- a/src/ast/call_statement_test.cc +++ b/src/ast/call_statement_test.cc @@ -14,6 +14,7 @@ #include "src/ast/call_statement.h" +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -30,25 +31,17 @@ TEST_F(CallStatementTest, Creation) { } TEST_F(CallStatementTest, IsCall) { - auto* c = create(nullptr); + auto* c = create(Call("f")); EXPECT_TRUE(c->Is()); } -TEST_F(CallStatementTest, IsValid) { - auto* c = create( - create(Expr("func"), ExpressionList{})); - EXPECT_TRUE(c->IsValid()); -} - -TEST_F(CallStatementTest, IsValid_MissingExpr) { - auto* c = create(nullptr); - EXPECT_FALSE(c->IsValid()); -} - -TEST_F(CallStatementTest, IsValid_InvalidExpr) { - auto* c = create( - create(nullptr, ast::ExpressionList{})); - EXPECT_FALSE(c->IsValid()); +TEST_F(CallStatementTest, Assert_NullCall) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr); + }, + "internal compiler error"); } TEST_F(CallStatementTest, ToStr) { diff --git a/src/ast/case_statement.cc b/src/ast/case_statement.cc index 5f4dc37b95..e95383c06a 100644 --- a/src/ast/case_statement.cc +++ b/src/ast/case_statement.cc @@ -24,7 +24,9 @@ namespace ast { CaseStatement::CaseStatement(const Source& source, CaseSelectorList selectors, BlockStatement* body) - : Base(source), selectors_(selectors), body_(body) {} + : Base(source), selectors_(selectors), body_(body) { + TINT_ASSERT(body_); +} CaseStatement::CaseStatement(CaseStatement&&) = default; @@ -38,10 +40,6 @@ CaseStatement* CaseStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, sel, b); } -bool CaseStatement::IsValid() const { - return body_ != nullptr && body_->IsValid(); -} - void CaseStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/case_statement.h b/src/ast/case_statement.h index ef9c1ffecb..6a61837644 100644 --- a/src/ast/case_statement.h +++ b/src/ast/case_statement.h @@ -56,9 +56,6 @@ class CaseStatement : public Castable { /// @return the newly cloned node CaseStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/case_statement_test.cc b/src/ast/case_statement_test.cc index 2f9c74c402..6e64f39187 100644 --- a/src/ast/case_statement_test.cc +++ b/src/ast/case_statement_test.cc @@ -14,6 +14,7 @@ #include "src/ast/case_statement.h" +#include "gtest/gtest-spi.h" #include "src/ast/discard_statement.h" #include "src/ast/if_statement.h" #include "src/ast/test_helper.h" @@ -89,36 +90,13 @@ TEST_F(CaseStatementTest, IsCase) { EXPECT_TRUE(c->Is()); } -TEST_F(CaseStatementTest, IsValid) { - auto* c = create(CaseSelectorList{}, - create(StatementList{})); - EXPECT_TRUE(c->IsValid()); -} - -TEST_F(CaseStatementTest, IsValid_NullBodyStatement) { - CaseSelectorList b; - b.push_back(create(ty.i32(), 2)); - - auto* body = create(StatementList{ - create(), - nullptr, - }); - auto* c = create(b, body); - EXPECT_FALSE(c->IsValid()); -} - -TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) { - CaseSelectorList b; - b.push_back(create(ty.i32(), 2)); - - auto* body = create( - - StatementList{ - create(nullptr, create(StatementList{}), - ElseStatementList{}), - }); - auto* c = create(CaseSelectorList{b}, body); - EXPECT_FALSE(c->IsValid()); +TEST_F(CaseStatementTest, Assert_NullBody) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(CaseSelectorList{}, nullptr); + }, + "internal compiler error"); } TEST_F(CaseStatementTest, ToStr_WithSelectors_i32) { diff --git a/src/ast/continue_statement.cc b/src/ast/continue_statement.cc index f5d5201226..64f2267544 100644 --- a/src/ast/continue_statement.cc +++ b/src/ast/continue_statement.cc @@ -33,10 +33,6 @@ ContinueStatement* ContinueStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src); } -bool ContinueStatement::IsValid() const { - return true; -} - void ContinueStatement::to_str(const semantic::Info&, std::ostream& out, size_t indent) const { diff --git a/src/ast/continue_statement.h b/src/ast/continue_statement.h index 512741fce7..f2be33a2ae 100644 --- a/src/ast/continue_statement.h +++ b/src/ast/continue_statement.h @@ -36,9 +36,6 @@ class ContinueStatement : public Castable { /// @return the newly cloned node ContinueStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/continue_statement_test.cc b/src/ast/continue_statement_test.cc index 356011e659..dd3fd94f23 100644 --- a/src/ast/continue_statement_test.cc +++ b/src/ast/continue_statement_test.cc @@ -34,11 +34,6 @@ TEST_F(ContinueStatementTest, IsContinue) { EXPECT_TRUE(stmt->Is()); } -TEST_F(ContinueStatementTest, IsValid) { - auto* stmt = create(); - EXPECT_TRUE(stmt->IsValid()); -} - TEST_F(ContinueStatementTest, ToStr) { auto* stmt = create(); EXPECT_EQ(str(stmt), R"(Continue{} diff --git a/src/ast/decoration.cc b/src/ast/decoration.cc index c7573f40ce..447105f029 100644 --- a/src/ast/decoration.cc +++ b/src/ast/decoration.cc @@ -39,9 +39,5 @@ std::ostream& operator<<(std::ostream& out, DecorationKind data) { return out << ""; } -bool Decoration::IsValid() const { - return true; -} - } // namespace ast } // namespace tint diff --git a/src/ast/decoration.h b/src/ast/decoration.h index 378ad7e3b1..32b1e60083 100644 --- a/src/ast/decoration.h +++ b/src/ast/decoration.h @@ -42,9 +42,6 @@ class Decoration : public Castable { /// @return the decoration kind virtual DecorationKind GetKind() const = 0; - /// @returns true if the node is valid - bool IsValid() const override; - protected: /// Constructor /// @param source the source of this decoration diff --git a/src/ast/discard_statement.cc b/src/ast/discard_statement.cc index a33373ff6d..c31ed8d9a7 100644 --- a/src/ast/discard_statement.cc +++ b/src/ast/discard_statement.cc @@ -33,10 +33,6 @@ DiscardStatement* DiscardStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src); } -bool DiscardStatement::IsValid() const { - return true; -} - void DiscardStatement::to_str(const semantic::Info&, std::ostream& out, size_t indent) const { diff --git a/src/ast/discard_statement.h b/src/ast/discard_statement.h index 14e96e439d..c2c6bb99f7 100644 --- a/src/ast/discard_statement.h +++ b/src/ast/discard_statement.h @@ -36,9 +36,6 @@ class DiscardStatement : public Castable { /// @return the newly cloned node DiscardStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/discard_statement_test.cc b/src/ast/discard_statement_test.cc index 8033abedc9..dc79806ca3 100644 --- a/src/ast/discard_statement_test.cc +++ b/src/ast/discard_statement_test.cc @@ -44,11 +44,6 @@ TEST_F(DiscardStatementTest, IsDiscard) { EXPECT_TRUE(stmt->Is()); } -TEST_F(DiscardStatementTest, IsValid) { - auto* stmt = create(); - EXPECT_TRUE(stmt->IsValid()); -} - TEST_F(DiscardStatementTest, ToStr) { auto* stmt = create(); EXPECT_EQ(str(stmt), R"(Discard{} diff --git a/src/ast/else_statement.cc b/src/ast/else_statement.cc index aa359e5174..67062479c6 100644 --- a/src/ast/else_statement.cc +++ b/src/ast/else_statement.cc @@ -24,7 +24,9 @@ namespace ast { ElseStatement::ElseStatement(const Source& source, Expression* condition, BlockStatement* body) - : Base(source), condition_(condition), body_(body) {} + : Base(source), condition_(condition), body_(body) { + TINT_ASSERT(body_); +} ElseStatement::ElseStatement(ElseStatement&&) = default; @@ -38,13 +40,6 @@ ElseStatement* ElseStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, cond, b); } -bool ElseStatement::IsValid() const { - if (body_ == nullptr || !body_->IsValid()) { - return false; - } - return condition_ == nullptr || condition_->IsValid(); -} - void ElseStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/else_statement.h b/src/ast/else_statement.h index 9e3401918f..a2c07c3ce1 100644 --- a/src/ast/else_statement.h +++ b/src/ast/else_statement.h @@ -53,9 +53,6 @@ class ElseStatement : public Castable { /// @return the newly cloned node ElseStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/else_statement_test.cc b/src/ast/else_statement_test.cc index e17e599f5e..175b09cc82 100644 --- a/src/ast/else_statement_test.cc +++ b/src/ast/else_statement_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/discard_statement.h" #include "src/ast/if_statement.h" #include "src/ast/test_helper.h" @@ -36,7 +37,7 @@ TEST_F(ElseStatementTest, Creation) { } TEST_F(ElseStatementTest, Creation_WithSource) { - auto* e = create(Source{Source::Location{20, 2}}, nullptr, + auto* e = create(Source{Source::Location{20, 2}}, Expr(true), create(StatementList{})); auto src = e->source(); EXPECT_EQ(src.range.begin.line, 20u); @@ -62,45 +63,13 @@ TEST_F(ElseStatementTest, HasContition_NullCondition) { EXPECT_FALSE(e->HasCondition()); } -TEST_F(ElseStatementTest, IsValid) { - auto* e = - create(nullptr, create(StatementList{})); - EXPECT_TRUE(e->IsValid()); -} - -TEST_F(ElseStatementTest, IsValid_WithBody) { - auto* body = create(StatementList{ - create(), - }); - auto* e = create(nullptr, body); - EXPECT_TRUE(e->IsValid()); -} - -TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) { - auto* body = create(StatementList{ - create(), - nullptr, - }); - auto* e = create(nullptr, body); - EXPECT_FALSE(e->IsValid()); -} - -TEST_F(ElseStatementTest, IsValid_InvalidCondition) { - auto* cond = create(nullptr); - auto* e = - create(cond, create(StatementList{})); - EXPECT_FALSE(e->IsValid()); -} - -TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) { - auto* body = create( - - StatementList{ - create(nullptr, create(StatementList{}), - ElseStatementList{}), - }); - auto* e = create(nullptr, body); - EXPECT_FALSE(e->IsValid()); +TEST_F(ElseStatementTest, Assert_NullBody) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.Expr(true), nullptr); + }, + "internal compiler error"); } TEST_F(ElseStatementTest, ToStr) { diff --git a/src/ast/fallthrough_statement.cc b/src/ast/fallthrough_statement.cc index 1dcf72df1a..d43221288f 100644 --- a/src/ast/fallthrough_statement.cc +++ b/src/ast/fallthrough_statement.cc @@ -34,10 +34,6 @@ FallthroughStatement* FallthroughStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src); } -bool FallthroughStatement::IsValid() const { - return true; -} - void FallthroughStatement::to_str(const semantic::Info&, std::ostream& out, size_t indent) const { diff --git a/src/ast/fallthrough_statement.h b/src/ast/fallthrough_statement.h index b0d14b08bd..cb586a0b90 100644 --- a/src/ast/fallthrough_statement.h +++ b/src/ast/fallthrough_statement.h @@ -36,9 +36,6 @@ class FallthroughStatement : public Castable { /// @return the newly cloned node FallthroughStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/fallthrough_statement_test.cc b/src/ast/fallthrough_statement_test.cc index 8072e1cf60..047af88869 100644 --- a/src/ast/fallthrough_statement_test.cc +++ b/src/ast/fallthrough_statement_test.cc @@ -42,11 +42,6 @@ TEST_F(FallthroughStatementTest, IsFallthrough) { EXPECT_TRUE(stmt->Is()); } -TEST_F(FallthroughStatementTest, IsValid) { - auto* stmt = create(); - EXPECT_TRUE(stmt->IsValid()); -} - TEST_F(FallthroughStatementTest, ToStr) { auto* stmt = create(); EXPECT_EQ(str(stmt), R"(Fallthrough{} diff --git a/src/ast/function.cc b/src/ast/function.cc index 5858867084..8f47a1b86e 100644 --- a/src/ast/function.cc +++ b/src/ast/function.cc @@ -34,7 +34,14 @@ Function::Function(const Source& source, params_(std::move(params)), return_type_(return_type), body_(body), - decorations_(std::move(decorations)) {} + decorations_(std::move(decorations)) { + for (auto* param : params_) { + TINT_ASSERT(param); + } + TINT_ASSERT(body_); + TINT_ASSERT(symbol_.IsValid()); + TINT_ASSERT(return_type_); +} Function::Function(Function&&) = default; @@ -73,23 +80,6 @@ Function* Function::Clone(CloneContext* ctx) const { return ctx->dst->create(src, sym, p, ret, b, decos); } -bool Function::IsValid() const { - for (auto* param : params_) { - if (param == nullptr || !param->IsValid()) - return false; - } - if (body_ == nullptr || !body_->IsValid()) { - return false; - } - if (!symbol_.IsValid()) { - return false; - } - if (return_type_ == nullptr) { - return false; - } - return true; -} - void Function::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/function.h b/src/ast/function.h index 8ac517e428..109c5df80f 100644 --- a/src/ast/function.h +++ b/src/ast/function.h @@ -89,9 +89,6 @@ class Function : public Castable { /// @return the newly cloned node Function* Clone(CloneContext* ctx) const override; - /// @returns true if the symbol and type are both present - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc index db7aee9146..39a478d798 100644 --- a/src/ast/function_test.cc +++ b/src/ast/function_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/discard_statement.h" #include "src/ast/stage_decoration.h" #include "src/ast/test_helper.h" @@ -47,80 +48,38 @@ TEST_F(FunctionTest, Creation_WithSource) { EXPECT_EQ(src.range.begin.column, 2u); } -TEST_F(FunctionTest, IsValid) { - VariableList params; - params.push_back(Var("var", ty.i32(), StorageClass::kNone)); - - auto* f = Func("func", params, ty.void_(), - StatementList{ - create(), - }, - FunctionDecorationList{}); - EXPECT_TRUE(f->IsValid()); +TEST_F(FunctionTest, Assert_InvalidName) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Func("", VariableList{}, b.ty.void_(), StatementList{}, + FunctionDecorationList{}); + }, + "internal compiler error"); } -TEST_F(FunctionTest, IsValid_InvalidName) { - VariableList params; - params.push_back(Var("var", ty.i32(), StorageClass::kNone)); - - auto* f = - Func("", params, ty.void_(), StatementList{}, FunctionDecorationList{}); - EXPECT_FALSE(f->IsValid()); +TEST_F(FunctionTest, Assert_NullReturnType) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Func("f", VariableList{}, nullptr, StatementList{}, + FunctionDecorationList{}); + }, + "internal compiler error"); } -TEST_F(FunctionTest, IsValid_MissingReturnType) { - VariableList params; - params.push_back(Var("var", ty.i32(), StorageClass::kNone)); +TEST_F(FunctionTest, Assert_NullParam) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + VariableList params; + params.push_back(b.Var("var", b.ty.i32(), StorageClass::kNone)); + params.push_back(nullptr); - auto* f = - Func("func", params, nullptr, StatementList{}, FunctionDecorationList{}); - EXPECT_FALSE(f->IsValid()); -} - -TEST_F(FunctionTest, IsValid_NullParam) { - VariableList params; - params.push_back(Var("var", ty.i32(), StorageClass::kNone)); - params.push_back(nullptr); - - auto* f = Func("func", params, ty.void_(), StatementList{}, - FunctionDecorationList{}); - EXPECT_FALSE(f->IsValid()); -} - -TEST_F(FunctionTest, IsValid_InvalidParam) { - VariableList params; - params.push_back(Var("var", nullptr, StorageClass::kNone)); - - auto* f = Func("func", params, ty.void_(), StatementList{}, - FunctionDecorationList{}); - EXPECT_FALSE(f->IsValid()); -} - -TEST_F(FunctionTest, IsValid_NullBodyStatement) { - VariableList params; - params.push_back(Var("var", ty.i32(), StorageClass::kNone)); - - auto* f = Func("func", params, ty.void_(), - StatementList{ - create(), - nullptr, - }, - FunctionDecorationList{}); - - EXPECT_FALSE(f->IsValid()); -} - -TEST_F(FunctionTest, IsValid_InvalidBodyStatement) { - VariableList params; - params.push_back(Var("var", ty.i32(), StorageClass::kNone)); - - auto* f = Func("func", params, ty.void_(), - StatementList{ - create(), - nullptr, - }, - FunctionDecorationList{}); - EXPECT_FALSE(f->IsValid()); + b.Func("f", params, b.ty.void_(), StatementList{}, + FunctionDecorationList{}); + }, + "internal compiler error"); } TEST_F(FunctionTest, ToStr) { diff --git a/src/ast/identifier_expression.cc b/src/ast/identifier_expression.cc index 1f8c671111..e996bac90e 100644 --- a/src/ast/identifier_expression.cc +++ b/src/ast/identifier_expression.cc @@ -22,7 +22,9 @@ namespace tint { namespace ast { IdentifierExpression::IdentifierExpression(const Source& source, Symbol sym) - : Base(source), sym_(sym) {} + : Base(source), sym_(sym) { + TINT_ASSERT(sym_.IsValid()); +} IdentifierExpression::IdentifierExpression(IdentifierExpression&&) = default; @@ -35,10 +37,6 @@ IdentifierExpression* IdentifierExpression::Clone(CloneContext* ctx) const { return ctx->dst->create(src, sym); } -bool IdentifierExpression::IsValid() const { - return sym_.IsValid(); -} - void IdentifierExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/identifier_expression.h b/src/ast/identifier_expression.h index 2794599882..396ad33a48 100644 --- a/src/ast/identifier_expression.h +++ b/src/ast/identifier_expression.h @@ -41,9 +41,6 @@ class IdentifierExpression : public Castable { /// @return the newly cloned node IdentifierExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/identifier_expression_test.cc b/src/ast/identifier_expression_test.cc index 3d22e1d66a..cea616ddc7 100644 --- a/src/ast/identifier_expression_test.cc +++ b/src/ast/identifier_expression_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -39,9 +40,13 @@ TEST_F(IdentifierExpressionTest, IsIdentifier) { EXPECT_TRUE(i->Is()); } -TEST_F(IdentifierExpressionTest, IsValid) { - auto* i = Expr("ident"); - EXPECT_TRUE(i->IsValid()); +TEST_F(IdentifierExpressionTest, Assert_InvalidSymbol) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Expr(""); + }, + "internal compiler error"); } TEST_F(IdentifierExpressionTest, ToStr) { diff --git a/src/ast/if_statement.cc b/src/ast/if_statement.cc index eee9e092cc..7a515db847 100644 --- a/src/ast/if_statement.cc +++ b/src/ast/if_statement.cc @@ -28,7 +28,13 @@ IfStatement::IfStatement(const Source& source, : Base(source), condition_(condition), body_(body), - else_statements_(std::move(else_stmts)) {} + else_statements_(std::move(else_stmts)) { + TINT_ASSERT(condition_); + TINT_ASSERT(body); + for (auto* el : else_statements_) { + TINT_ASSERT(el); + } +} IfStatement::IfStatement(IfStatement&&) = default; @@ -43,30 +49,6 @@ IfStatement* IfStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, cond, b, el); } -bool IfStatement::IsValid() const { - if (condition_ == nullptr || !condition_->IsValid()) { - return false; - } - if (body_ == nullptr || !body_->IsValid()) { - return false; - } - - bool found_else = false; - for (auto* el : else_statements_) { - // Else statement must be last - if (found_else) - return false; - - if (el == nullptr || !el->IsValid()) - return false; - - if (el->condition() == nullptr) - found_else = true; - } - - return true; -} - void IfStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/if_statement.h b/src/ast/if_statement.h index 4c578aa9c4..cf2f09a65d 100644 --- a/src/ast/if_statement.h +++ b/src/ast/if_statement.h @@ -57,9 +57,6 @@ class IfStatement : public Castable { /// @return the newly cloned node IfStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/if_statement_test.cc b/src/ast/if_statement_test.cc index a222886c45..dcc3342b55 100644 --- a/src/ast/if_statement_test.cc +++ b/src/ast/if_statement_test.cc @@ -14,6 +14,7 @@ #include "src/ast/if_statement.h" +#include "gtest/gtest-spi.h" #include "src/ast/discard_statement.h" #include "src/ast/test_helper.h" @@ -36,128 +37,37 @@ TEST_F(IfStatementTest, Creation) { TEST_F(IfStatementTest, IsIf) { auto* stmt = create( - nullptr, create(StatementList{}), ElseStatementList{}); + Expr(true), create(StatementList{}), ElseStatementList{}); EXPECT_TRUE(stmt->Is()); } -TEST_F(IfStatementTest, IsValid) { - auto* cond = Expr("cond"); - auto* body = - create(StatementList{create()}); - auto* stmt = create(cond, body, ElseStatementList{}); - EXPECT_TRUE(stmt->IsValid()); +TEST_F(IfStatementTest, Assert_NullCondition) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + auto* body = b.create(StatementList{}); + b.create(nullptr, body, ElseStatementList{}); + }, + "internal compiler error"); } -TEST_F(IfStatementTest, IsValid_WithElseStatements) { - auto* cond = Expr("cond"); - auto* body = - create(StatementList{create()}); - auto* stmt = create( - cond, body, - ElseStatementList{ - create(Expr("Ident"), - create(StatementList{})), - create(nullptr, - create(StatementList{})), - }); - EXPECT_TRUE(stmt->IsValid()); +TEST_F(IfStatementTest, Assert_NullBody) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.Expr(true), nullptr, ElseStatementList{}); + }, + "internal compiler error"); } -TEST_F(IfStatementTest, IsValid_MissingCondition) { - auto* body = - create(StatementList{create()}); - auto* stmt = create(nullptr, body, ElseStatementList{}); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(IfStatementTest, IsValid_InvalidCondition) { - auto* cond = Expr(""); - auto* body = - create(StatementList{create()}); - auto* stmt = create(cond, body, ElseStatementList{}); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(IfStatementTest, IsValid_NullBodyStatement) { - auto* cond = Expr("cond"); - auto* body = create(StatementList{ - create(), - nullptr, - }); - auto* stmt = create(cond, body, ElseStatementList{}); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) { - auto* cond = Expr("cond"); - auto* body = create( - - StatementList{ - create(), - create(nullptr, create(StatementList{}), - ast::ElseStatementList{}), - }); - auto* stmt = create(cond, body, ElseStatementList{}); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(IfStatementTest, IsValid_NullElseStatement) { - auto* cond = Expr("cond"); - auto* body = - create(StatementList{create()}); - auto* stmt = create( - cond, body, - ElseStatementList{ - create(Expr("Ident"), - create(StatementList{})), - create(nullptr, - create(StatementList{})), - nullptr, - }); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(IfStatementTest, IsValid_InvalidElseStatement) { - auto* cond = Expr("cond"); - auto* body = - create(StatementList{create()}); - auto* stmt = create( - cond, body, - ElseStatementList{ - create(Expr(""), - create(StatementList{})), - }); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) { - auto* cond = Expr("cond"); - auto* body = - create(StatementList{create()}); - auto* stmt = create( - cond, body, - ElseStatementList{ - create(nullptr, - create(StatementList{})), - create(nullptr, - create(StatementList{})), - }); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(IfStatementTest, IsValid_ElseNotLast) { - auto* cond = Expr("cond"); - auto* body = - create(StatementList{create()}); - auto* stmt = create( - cond, body, - ElseStatementList{ - create(nullptr, - create(StatementList{})), - create(Expr("Ident"), - create(StatementList{})), - }); - EXPECT_FALSE(stmt->IsValid()); +TEST_F(IfStatementTest, Assert_NullElseStatement) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + auto* body = b.create(StatementList{}); + b.create(b.Expr(true), body, ElseStatementList{nullptr}); + }, + "internal compiler error"); } TEST_F(IfStatementTest, ToStr) { diff --git a/src/ast/literal.cc b/src/ast/literal.cc index f6a9cebe68..3d1b063d11 100644 --- a/src/ast/literal.cc +++ b/src/ast/literal.cc @@ -24,10 +24,6 @@ Literal::Literal(const Source& source, type::Type* type) Literal::~Literal() = default; -bool Literal::IsValid() const { - return true; -} - void Literal::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/literal.h b/src/ast/literal.h index 826c0bcfab..70039c9f45 100644 --- a/src/ast/literal.h +++ b/src/ast/literal.h @@ -30,9 +30,6 @@ class Literal : public Castable { /// @returns the type of the literal type::Type* type() const { return type_; } - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/loop_statement.cc b/src/ast/loop_statement.cc index 66774a8ce4..962db02237 100644 --- a/src/ast/loop_statement.cc +++ b/src/ast/loop_statement.cc @@ -24,7 +24,9 @@ namespace ast { LoopStatement::LoopStatement(const Source& source, BlockStatement* body, BlockStatement* continuing) - : Base(source), body_(body), continuing_(continuing) {} + : Base(source), body_(body), continuing_(continuing) { + TINT_ASSERT(body_); +} LoopStatement::LoopStatement(LoopStatement&&) = default; @@ -38,16 +40,6 @@ LoopStatement* LoopStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, b, cont); } -bool LoopStatement::IsValid() const { - if (body_ == nullptr || !body_->IsValid()) { - return false; - } - if (continuing_ == nullptr || !continuing_->IsValid()) { - return false; - } - return true; -} - void LoopStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/loop_statement.h b/src/ast/loop_statement.h index c0bc2dc88e..f2ee7adc22 100644 --- a/src/ast/loop_statement.h +++ b/src/ast/loop_statement.h @@ -54,9 +54,6 @@ class LoopStatement : public Castable { /// @return the newly cloned node LoopStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/loop_statement_test.cc b/src/ast/loop_statement_test.cc index 7577773a72..f1e42b1457 100644 --- a/src/ast/loop_statement_test.cc +++ b/src/ast/loop_statement_test.cc @@ -14,6 +14,7 @@ #include "src/ast/loop_statement.h" +#include "gtest/gtest-spi.h" #include "src/ast/discard_statement.h" #include "src/ast/if_statement.h" #include "src/ast/test_helper.h" @@ -78,88 +79,13 @@ TEST_F(LoopStatementTest, HasContinuing_WithContinuing) { EXPECT_TRUE(l->has_continuing()); } -TEST_F(LoopStatementTest, IsValid) { - auto* body = - create(StatementList{create()}); - - auto* continuing = - create(StatementList{create()}); - - auto* l = create(body, continuing); - EXPECT_TRUE(l->IsValid()); -} - -TEST_F(LoopStatementTest, IsValid_WithoutContinuing) { - auto* body = - create(StatementList{create()}); - - auto* l = - create(body, create(StatementList{})); - EXPECT_TRUE(l->IsValid()); -} - -TEST_F(LoopStatementTest, IsValid_WithoutBody) { - auto* l = create(create(StatementList{}), - create(StatementList{})); - EXPECT_TRUE(l->IsValid()); -} - -TEST_F(LoopStatementTest, IsValid_NullBodyStatement) { - auto* body = create(StatementList{ - create(), - nullptr, - }); - - auto* continuing = - create(StatementList{create()}); - - auto* l = create(body, continuing); - EXPECT_FALSE(l->IsValid()); -} - -TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) { - auto* body = create( - - StatementList{ - create(), - create(nullptr, create(StatementList{}), - ElseStatementList{}), - }); - - auto* continuing = - create(StatementList{create()}); - - auto* l = create(body, continuing); - EXPECT_FALSE(l->IsValid()); -} - -TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) { - auto* body = - create(StatementList{create()}); - - auto* continuing = create(StatementList{ - create(), - nullptr, - }); - - auto* l = create(body, continuing); - EXPECT_FALSE(l->IsValid()); -} - -TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) { - auto* body = - create(StatementList{create()}); - - auto* continuing = create( - - StatementList{ - create(), - create(nullptr, create(StatementList{}), - ElseStatementList{}), - }); - - auto* l = create(body, continuing); - EXPECT_FALSE(l->IsValid()); +TEST_F(LoopStatementTest, Assert_NullBody) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr, nullptr); + }, + "internal compiler error"); } TEST_F(LoopStatementTest, ToStr) { diff --git a/src/ast/member_accessor_expression.cc b/src/ast/member_accessor_expression.cc index 7ad670789b..6e8e9a9dce 100644 --- a/src/ast/member_accessor_expression.cc +++ b/src/ast/member_accessor_expression.cc @@ -24,7 +24,10 @@ namespace ast { MemberAccessorExpression::MemberAccessorExpression(const Source& source, Expression* structure, IdentifierExpression* member) - : Base(source), struct_(structure), member_(member) {} + : Base(source), struct_(structure), member_(member) { + TINT_ASSERT(structure); + TINT_ASSERT(member); +} MemberAccessorExpression::MemberAccessorExpression(MemberAccessorExpression&&) = default; @@ -40,16 +43,6 @@ MemberAccessorExpression* MemberAccessorExpression::Clone( return ctx->dst->create(src, str, mem); } -bool MemberAccessorExpression::IsValid() const { - if (struct_ == nullptr || !struct_->IsValid()) { - return false; - } - if (member_ == nullptr || !member_->IsValid()) { - return false; - } - return true; -} - void MemberAccessorExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/member_accessor_expression.h b/src/ast/member_accessor_expression.h index b3a87aba06..ac2c8bf81d 100644 --- a/src/ast/member_accessor_expression.h +++ b/src/ast/member_accessor_expression.h @@ -46,9 +46,6 @@ class MemberAccessorExpression /// @return the newly cloned node MemberAccessorExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/member_accessor_expression_test.cc b/src/ast/member_accessor_expression_test.cc index 06f004f1d1..44c30d1e39 100644 --- a/src/ast/member_accessor_expression_test.cc +++ b/src/ast/member_accessor_expression_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -43,30 +44,22 @@ TEST_F(MemberAccessorExpressionTest, IsMemberAccessor) { EXPECT_TRUE(stmt->Is()); } -TEST_F(MemberAccessorExpressionTest, IsValid) { - auto* stmt = - create(Expr("structure"), Expr("member")); - EXPECT_TRUE(stmt->IsValid()); +TEST_F(MemberAccessorExpressionTest, Assert_NullStruct) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr, b.Expr("member")); + }, + "internal compiler error"); } -TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) { - auto* stmt = create(nullptr, Expr("member")); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) { - auto* stmt = create(Expr(""), Expr("member")); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) { - auto* stmt = create(Expr("structure"), nullptr); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) { - auto* stmt = create(Expr("structure"), Expr("")); - EXPECT_FALSE(stmt->IsValid()); +TEST_F(MemberAccessorExpressionTest, Assert_NullMember) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.Expr("struct"), nullptr); + }, + "internal compiler error"); } TEST_F(MemberAccessorExpressionTest, ToStr) { diff --git a/src/ast/module.cc b/src/ast/module.cc index ed23908333..892bcced24 100644 --- a/src/ast/module.cc +++ b/src/ast/module.cc @@ -47,46 +47,6 @@ Module::Module(const Source& source, std::vector global_decls) Module::~Module() = default; -bool Module::IsValid() const { - for (auto* decl : global_declarations_) { - if (decl == nullptr) { - return false; - } - } - for (auto* var : global_variables_) { - if (var == nullptr || !var->IsValid()) { - return false; - } - } - for (auto* const ty : constructed_types_) { - if (ty == nullptr) { - return false; - } - if (auto* alias = ty->As()) { - if (alias->type() == nullptr) { - return false; - } - if (auto* str = alias->type()->As()) { - if (!str->symbol().IsValid()) { - return false; - } - } - } else if (auto* str = ty->As()) { - if (!str->symbol().IsValid()) { - return false; - } - } else { - return false; - } - } - for (auto* func : functions_) { - if (func == nullptr || !func->IsValid()) { - return false; - } - } - return true; -} - Module* Module::Clone(CloneContext* ctx) const { auto* out = ctx->dst->create(); out->Copy(ctx, this); diff --git a/src/ast/module.h b/src/ast/module.h index 91a4f87040..0f518e1edf 100644 --- a/src/ast/module.h +++ b/src/ast/module.h @@ -48,6 +48,7 @@ class Module : public Castable { /// Add a global variable to the Builder /// @param var the variable to add void AddGlobalVariable(ast::Variable* var) { + TINT_ASSERT(var); global_variables_.push_back(var); global_declarations_.push_back(var); } @@ -62,6 +63,7 @@ class Module : public Castable { /// The type must be an alias or a struct. /// @param type the constructed type to add void AddConstructedType(type::Type* type) { + TINT_ASSERT(type); constructed_types_.push_back(type); global_declarations_.push_back(type); } @@ -74,6 +76,7 @@ class Module : public Castable { /// Add a function to the Builder /// @param func the function to add void AddFunction(ast::Function* func) { + TINT_ASSERT(func); functions_.push_back(func); global_declarations_.push_back(func); } @@ -81,9 +84,6 @@ class Module : public Castable { /// @returns the functions declared in the translation unit const FunctionList& Functions() const { return functions_; } - /// @returns true if all required fields in the AST are present. - bool IsValid() const override; - /// Clones this node and all transitive child nodes using the `CloneContext` /// `ctx`. /// @param ctx the clone context diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc index b77435f8e5..ff3288ea0f 100644 --- a/src/ast/module_test.cc +++ b/src/ast/module_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -45,78 +46,40 @@ TEST_F(ModuleTest, LookupFunctionMissing) { program.AST().Functions().Find(program.Symbols().Get("Missing"))); } -TEST_F(ModuleTest, IsValid_Empty) { - Program program(std::move(*this)); - EXPECT_TRUE(program.AST().IsValid()); +TEST_F(ModuleTest, Assert_Null_GlobalVariable) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder builder; + builder.AST().AddGlobalVariable(nullptr); + }, + "internal compiler error"); } -TEST_F(ModuleTest, IsValid_GlobalVariable) { - Global("var", ty.f32(), StorageClass::kInput); - Program program(std::move(*this)); - EXPECT_TRUE(program.AST().IsValid()); +TEST_F(ModuleTest, Assert_Invalid_GlobalVariable) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder builder; + builder.Global("var", nullptr, StorageClass::kInput); + }, + "internal compiler error"); } -TEST_F(ModuleTest, IsValid_Null_GlobalVariable) { - AST().AddGlobalVariable(nullptr); - Program program(std::move(*this)); - EXPECT_FALSE(program.AST().IsValid()); +TEST_F(ModuleTest, Assert_Null_ConstructedType) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder builder; + builder.AST().AddConstructedType(nullptr); + }, + "internal compiler error"); } -TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) { - Global("var", nullptr, StorageClass::kInput); - Program program(std::move(*this)); - EXPECT_FALSE(program.AST().IsValid()); -} - -TEST_F(ModuleTest, IsValid_Alias) { - auto* alias = ty.alias("alias", ty.f32()); - AST().AddConstructedType(alias); - Program program(std::move(*this)); - EXPECT_TRUE(program.AST().IsValid()); -} - -TEST_F(ModuleTest, IsValid_Null_Alias) { - AST().AddConstructedType(nullptr); - Program program(std::move(*this)); - EXPECT_FALSE(program.AST().IsValid()); -} - -TEST_F(ModuleTest, IsValid_Struct) { - auto* st = ty.struct_("name", {}); - auto* alias = ty.alias("name", st); - AST().AddConstructedType(alias); - Program program(std::move(*this)); - EXPECT_TRUE(program.AST().IsValid()); -} - -TEST_F(ModuleTest, IsValid_Struct_EmptyName) { - auto* st = ty.struct_("", {}); - auto* alias = ty.alias("name", st); - AST().AddConstructedType(alias); - Program program(std::move(*this)); - EXPECT_FALSE(program.AST().IsValid()); -} - -TEST_F(ModuleTest, IsValid_Function) { - Func("main", VariableList(), ty.f32(), StatementList{}, - ast::FunctionDecorationList{}); - - Program program(std::move(*this)); - EXPECT_TRUE(program.AST().IsValid()); -} - -TEST_F(ModuleTest, IsValid_Null_Function) { - AST().AddFunction(nullptr); - Program program(std::move(*this)); - EXPECT_FALSE(program.AST().IsValid()); -} - -TEST_F(ModuleTest, IsValid_Invalid_Function) { - Func("main", VariableList{}, nullptr, StatementList{}, - ast::FunctionDecorationList{}); - - Program program(std::move(*this)); - EXPECT_FALSE(program.AST().IsValid()); +TEST_F(ModuleTest, Assert_Null_Function) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder builder; + builder.AST().AddFunction(nullptr); + }, + "internal compiler error"); } } // namespace diff --git a/src/ast/node.h b/src/ast/node.h index fad460f17c..157f93eb3b 100644 --- a/src/ast/node.h +++ b/src/ast/node.h @@ -40,9 +40,6 @@ class Node : public Castable { /// @returns the node source data const Source& source() const { return source_; } - /// @returns true if the node is valid - virtual bool IsValid() const = 0; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/return_statement.cc b/src/ast/return_statement.cc index 38df855ea8..7c5e3a1319 100644 --- a/src/ast/return_statement.cc +++ b/src/ast/return_statement.cc @@ -38,13 +38,6 @@ ReturnStatement* ReturnStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, ret); } -bool ReturnStatement::IsValid() const { - if (value_ != nullptr) { - return value_->IsValid(); - } - return true; -} - void ReturnStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/return_statement.h b/src/ast/return_statement.h index 0079248d81..77f48052c2 100644 --- a/src/ast/return_statement.h +++ b/src/ast/return_statement.h @@ -46,9 +46,6 @@ class ReturnStatement : public Castable { /// @return the newly cloned node ReturnStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/return_statement_test.cc b/src/ast/return_statement_test.cc index 81fd712660..d55e360170 100644 --- a/src/ast/return_statement_test.cc +++ b/src/ast/return_statement_test.cc @@ -52,23 +52,6 @@ TEST_F(ReturnStatementTest, HasValue_WithValue) { EXPECT_TRUE(r->has_value()); } -TEST_F(ReturnStatementTest, IsValid_WithoutValue) { - auto* r = create(); - EXPECT_TRUE(r->IsValid()); -} - -TEST_F(ReturnStatementTest, IsValid_WithValue) { - auto* expr = Expr("expr"); - auto* r = create(expr); - EXPECT_TRUE(r->IsValid()); -} - -TEST_F(ReturnStatementTest, IsValid_InvalidValue) { - auto* expr = Expr(""); - auto* r = create(expr); - EXPECT_FALSE(r->IsValid()); -} - TEST_F(ReturnStatementTest, ToStr_WithValue) { auto* expr = Expr("expr"); auto* r = create(expr); diff --git a/src/ast/scalar_constructor_expression.cc b/src/ast/scalar_constructor_expression.cc index e82c17cd33..4f0ecced51 100644 --- a/src/ast/scalar_constructor_expression.cc +++ b/src/ast/scalar_constructor_expression.cc @@ -22,8 +22,10 @@ namespace tint { namespace ast { ScalarConstructorExpression::ScalarConstructorExpression(const Source& source, - Literal* litearl) - : Base(source), literal_(litearl) {} + Literal* literal) + : Base(source), literal_(literal) { + TINT_ASSERT(literal); +} ScalarConstructorExpression::ScalarConstructorExpression( ScalarConstructorExpression&&) = default; @@ -38,10 +40,6 @@ ScalarConstructorExpression* ScalarConstructorExpression::Clone( return ctx->dst->create(src, lit); } -bool ScalarConstructorExpression::IsValid() const { - return literal_ != nullptr; -} - void ScalarConstructorExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/scalar_constructor_expression.h b/src/ast/scalar_constructor_expression.h index fe6c6d9fb5..3b56357efd 100644 --- a/src/ast/scalar_constructor_expression.h +++ b/src/ast/scalar_constructor_expression.h @@ -42,9 +42,6 @@ class ScalarConstructorExpression /// @return the newly cloned node ScalarConstructorExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/scalar_constructor_expression_test.cc b/src/ast/scalar_constructor_expression_test.cc index aadc5be2f1..7d8263807e 100644 --- a/src/ast/scalar_constructor_expression_test.cc +++ b/src/ast/scalar_constructor_expression_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -33,14 +34,13 @@ TEST_F(ScalarConstructorExpressionTest, Creation_WithSource) { EXPECT_EQ(src.range.begin.column, 2u); } -TEST_F(ScalarConstructorExpressionTest, IsValid) { - auto* c = Expr(true); - EXPECT_TRUE(c->IsValid()); -} - -TEST_F(ScalarConstructorExpressionTest, IsValid_MissingLiteral) { - auto* c = create(nullptr); - EXPECT_FALSE(c->IsValid()); +TEST_F(ScalarConstructorExpressionTest, Assert_NullLiteral) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr); + }, + "internal compiler error"); } TEST_F(ScalarConstructorExpressionTest, ToStr) { diff --git a/src/ast/struct.cc b/src/ast/struct.cc index c21c17e534..66043995e2 100644 --- a/src/ast/struct.cc +++ b/src/ast/struct.cc @@ -27,7 +27,14 @@ Struct::Struct(const Source& source, StructDecorationList decorations) : Base(source), members_(std::move(members)), - decorations_(std::move(decorations)) {} + decorations_(std::move(decorations)) { + for (auto* mem : members_) { + TINT_ASSERT(mem); + } + for (auto* deco : decorations_) { + TINT_ASSERT(deco); + } +} Struct::Struct(Struct&&) = default; @@ -59,15 +66,6 @@ Struct* Struct::Clone(CloneContext* ctx) const { return ctx->dst->create(src, mem, decos); } -bool Struct::IsValid() const { - for (auto* mem : members_) { - if (mem == nullptr || !mem->IsValid()) { - return false; - } - } - return true; -} - void Struct::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/struct.h b/src/ast/struct.h index 752ea055cd..58f165fbe3 100644 --- a/src/ast/struct.h +++ b/src/ast/struct.h @@ -58,9 +58,6 @@ class Struct : public Castable { /// @return the newly cloned node Struct* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/struct_member.cc b/src/ast/struct_member.cc index f6146c1068..4a3a18a375 100644 --- a/src/ast/struct_member.cc +++ b/src/ast/struct_member.cc @@ -28,7 +28,13 @@ StructMember::StructMember(const Source& source, : Base(source), symbol_(sym), type_(type), - decorations_(std::move(decorations)) {} + decorations_(std::move(decorations)) { + TINT_ASSERT(type); + TINT_ASSERT(symbol_.IsValid()); + for (auto* deco : decorations_) { + TINT_ASSERT(deco); + } +} StructMember::StructMember(StructMember&&) = default; @@ -61,18 +67,6 @@ StructMember* StructMember::Clone(CloneContext* ctx) const { return ctx->dst->create(src, sym, ty, decos); } -bool StructMember::IsValid() const { - if (type_ == nullptr || !symbol_.IsValid()) { - return false; - } - for (auto* deco : decorations_) { - if (deco == nullptr) { - return false; - } - } - return true; -} - void StructMember::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/struct_member.h b/src/ast/struct_member.h index 92491e57cb..0595b34c73 100644 --- a/src/ast/struct_member.h +++ b/src/ast/struct_member.h @@ -59,9 +59,6 @@ class StructMember : public Castable { /// @return the newly cloned node StructMember* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/struct_member_test.cc b/src/ast/struct_member_test.cc index 1b835de6a2..17c4425560 100644 --- a/src/ast/struct_member_test.cc +++ b/src/ast/struct_member_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -45,24 +46,31 @@ TEST_F(StructMemberTest, CreationWithSource) { EXPECT_EQ(st->source().range.end.column, 8u); } -TEST_F(StructMemberTest, IsValid) { - auto* st = Member("a", ty.i32()); - EXPECT_TRUE(st->IsValid()); +TEST_F(StructMemberTest, Assert_EmptySymbol) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Member("", b.ty.i32()); + }, + "internal compiler error"); } -TEST_F(StructMemberTest, IsValid_EmptySymbol) { - auto* st = Member("", ty.i32()); - EXPECT_FALSE(st->IsValid()); +TEST_F(StructMemberTest, Assert_NullType) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Member("a", nullptr); + }, + "internal compiler error"); } -TEST_F(StructMemberTest, IsValid_NullType) { - auto* st = Member("a", nullptr); - EXPECT_FALSE(st->IsValid()); -} - -TEST_F(StructMemberTest, IsValid_Null_Decoration) { - auto* st = Member("a", ty.i32(), {MemberOffset(4), nullptr}); - EXPECT_FALSE(st->IsValid()); +TEST_F(StructMemberTest, Assert_NullDecoration) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Member("a", b.ty.i32(), {b.MemberOffset(4), nullptr}); + }, + "internal compiler error"); } TEST_F(StructMemberTest, ToStr) { diff --git a/src/ast/struct_test.cc b/src/ast/struct_test.cc index f2bd221aee..421c50f714 100644 --- a/src/ast/struct_test.cc +++ b/src/ast/struct_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/struct_block_decoration.h" #include "src/ast/test_helper.h" @@ -62,21 +63,24 @@ TEST_F(StructTest, CreationWithSourceAndDecorations) { EXPECT_EQ(s->source().range.end.column, 8u); } -TEST_F(StructTest, IsValid) { - auto* s = create(StructMemberList{}, StructDecorationList{}); - EXPECT_TRUE(s->IsValid()); +TEST_F(StructTest, Assert_Null_StructMember) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(StructMemberList{b.Member("a", b.ty.i32()), nullptr}, + StructDecorationList{}); + }, + "internal compiler error"); } -TEST_F(StructTest, IsValid_Null_StructMember) { - auto* s = create(StructMemberList{Member("a", ty.i32()), nullptr}, - StructDecorationList{}); - EXPECT_FALSE(s->IsValid()); -} - -TEST_F(StructTest, IsValid_Invalid_StructMember) { - auto* s = create(StructMemberList{Member("", ty.i32())}, - ast::StructDecorationList{}); - EXPECT_FALSE(s->IsValid()); +TEST_F(StructTest, Assert_Null_Decoration) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(StructMemberList{b.Member("a", b.ty.i32())}, + StructDecorationList{nullptr}); + }, + "internal compiler error"); } TEST_F(StructTest, ToStr) { diff --git a/src/ast/switch_statement.cc b/src/ast/switch_statement.cc index e196878fbf..c413dd2dd8 100644 --- a/src/ast/switch_statement.cc +++ b/src/ast/switch_statement.cc @@ -24,7 +24,12 @@ namespace ast { SwitchStatement::SwitchStatement(const Source& source, Expression* condition, CaseStatementList body) - : Base(source), condition_(condition), body_(body) {} + : Base(source), condition_(condition), body_(body) { + TINT_ASSERT(condition_); + for (auto* stmt : body_) { + TINT_ASSERT(stmt); + } +} SwitchStatement::SwitchStatement(SwitchStatement&&) = default; @@ -38,18 +43,6 @@ SwitchStatement* SwitchStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, cond, b); } -bool SwitchStatement::IsValid() const { - if (condition_ == nullptr || !condition_->IsValid()) { - return false; - } - for (auto* stmt : body_) { - if (stmt == nullptr || !stmt->IsValid()) { - return false; - } - } - return true; -} - void SwitchStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/switch_statement.h b/src/ast/switch_statement.h index d3d061d140..0f78635603 100644 --- a/src/ast/switch_statement.h +++ b/src/ast/switch_statement.h @@ -49,9 +49,6 @@ class SwitchStatement : public Castable { /// @return the newly cloned node SwitchStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/switch_statement_test.cc b/src/ast/switch_statement_test.cc index 036cb8c283..4373c2d625 100644 --- a/src/ast/switch_statement_test.cc +++ b/src/ast/switch_statement_test.cc @@ -14,6 +14,7 @@ #include "src/ast/switch_statement.h" +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -61,69 +62,26 @@ TEST_F(SwitchStatementTest, IsSwitch) { EXPECT_TRUE(stmt->Is()); } -TEST_F(SwitchStatementTest, IsValid) { - CaseSelectorList lit; - lit.push_back(create(ty.i32(), 2)); - - auto* ident = Expr("ident"); - CaseStatementList body; - body.push_back( - create(lit, create(StatementList{}))); - - auto* stmt = create(ident, body); - EXPECT_TRUE(stmt->IsValid()); +TEST_F(SwitchStatementTest, Assert_Null_Condition) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + CaseStatementList cases; + cases.push_back( + b.create(CaseSelectorList{b.Literal(1)}, + b.create(StatementList{}))); + b.create(nullptr, cases); + }, + "internal compiler error"); } -TEST_F(SwitchStatementTest, IsValid_Null_Condition) { - CaseSelectorList lit; - lit.push_back(create(ty.i32(), 2)); - - CaseStatementList body; - body.push_back( - create(lit, create(StatementList{}))); - - auto* stmt = create(nullptr, body); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) { - CaseSelectorList lit; - lit.push_back(create(ty.i32(), 2)); - - auto* ident = Expr(""); - CaseStatementList body; - body.push_back( - create(lit, create(StatementList{}))); - - auto* stmt = create(ident, body); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) { - CaseSelectorList lit; - lit.push_back(create(ty.i32(), 2)); - - auto* ident = Expr("ident"); - CaseStatementList body; - body.push_back( - create(lit, create(StatementList{}))); - body.push_back(nullptr); - - auto* stmt = create(ident, body); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) { - auto* ident = Expr("ident"); - - auto* case_body = create(StatementList{ - nullptr, - }); - CaseStatementList body; - body.push_back(create(CaseSelectorList{}, case_body)); - - auto* stmt = create(ident, body); - EXPECT_FALSE(stmt->IsValid()); +TEST_F(SwitchStatementTest, Assert_Null_CaseStatement) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.Expr(true), CaseStatementList{nullptr}); + }, + "internal compiler error"); } TEST_F(SwitchStatementTest, ToStr_Empty) { diff --git a/src/ast/type_constructor_expression.cc b/src/ast/type_constructor_expression.cc index c4f42ae30d..edf78facba 100644 --- a/src/ast/type_constructor_expression.cc +++ b/src/ast/type_constructor_expression.cc @@ -24,7 +24,12 @@ namespace ast { TypeConstructorExpression::TypeConstructorExpression(const Source& source, type::Type* type, ExpressionList values) - : Base(source), type_(type), values_(std::move(values)) {} + : Base(source), type_(type), values_(std::move(values)) { + TINT_ASSERT(type); + for (auto* val : values_) { + TINT_ASSERT(val); + } +} TypeConstructorExpression::TypeConstructorExpression( TypeConstructorExpression&&) = default; @@ -40,21 +45,6 @@ TypeConstructorExpression* TypeConstructorExpression::Clone( return ctx->dst->create(src, ty, vals); } -bool TypeConstructorExpression::IsValid() const { - if (values_.empty()) { - return true; - } - if (type_ == nullptr) { - return false; - } - for (auto* val : values_) { - if (val == nullptr || !val->IsValid()) { - return false; - } - } - return true; -} - void TypeConstructorExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/type_constructor_expression.h b/src/ast/type_constructor_expression.h index 30c5bbefa3..938166583e 100644 --- a/src/ast/type_constructor_expression.h +++ b/src/ast/type_constructor_expression.h @@ -48,9 +48,6 @@ class TypeConstructorExpression /// @return the newly cloned node TypeConstructorExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/type_constructor_expression_test.cc b/src/ast/type_constructor_expression_test.cc index d392294804..b6c0e287d7 100644 --- a/src/ast/type_constructor_expression_test.cc +++ b/src/ast/type_constructor_expression_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -49,44 +50,23 @@ TEST_F(TypeConstructorExpressionTest, IsTypeConstructor) { EXPECT_TRUE(t->Is()); } -TEST_F(TypeConstructorExpressionTest, IsValid) { - ExpressionList expr; - expr.push_back(Expr("expr")); - - auto* t = create(ty.f32(), expr); - EXPECT_TRUE(t->IsValid()); +TEST_F(TypeConstructorExpressionTest, Assert_NullType) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr, ExpressionList{b.Expr(1)}); + }, + "internal compiler error"); } -TEST_F(TypeConstructorExpressionTest, IsValid_EmptyValue) { - ExpressionList expr; - - auto* t = create(ty.f32(), expr); - EXPECT_TRUE(t->IsValid()); -} - -TEST_F(TypeConstructorExpressionTest, IsValid_NullType) { - ExpressionList expr; - expr.push_back(Expr("expr")); - - auto* t = create(nullptr, expr); - EXPECT_FALSE(t->IsValid()); -} - -TEST_F(TypeConstructorExpressionTest, IsValid_NullValue) { - ExpressionList expr; - expr.push_back(Expr("expr")); - expr.push_back(nullptr); - - auto* t = create(ty.f32(), expr); - EXPECT_FALSE(t->IsValid()); -} - -TEST_F(TypeConstructorExpressionTest, IsValid_InvalidValue) { - ExpressionList expr; - expr.push_back(Expr("")); - - auto* t = create(ty.f32(), expr); - EXPECT_FALSE(t->IsValid()); +TEST_F(TypeConstructorExpressionTest, Assert_NullValue) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(b.ty.i32(), + ExpressionList{nullptr}); + }, + "internal compiler error"); } TEST_F(TypeConstructorExpressionTest, ToStr) { diff --git a/src/ast/unary_op_expression.cc b/src/ast/unary_op_expression.cc index 3e5305b375..166d3f0fcf 100644 --- a/src/ast/unary_op_expression.cc +++ b/src/ast/unary_op_expression.cc @@ -24,7 +24,9 @@ namespace ast { UnaryOpExpression::UnaryOpExpression(const Source& source, UnaryOp op, Expression* expr) - : Base(source), op_(op), expr_(expr) {} + : Base(source), op_(op), expr_(expr) { + TINT_ASSERT(expr_); +} UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default; @@ -37,10 +39,6 @@ UnaryOpExpression* UnaryOpExpression::Clone(CloneContext* ctx) const { return ctx->dst->create(src, op_, e); } -bool UnaryOpExpression::IsValid() const { - return expr_ != nullptr && expr_->IsValid(); -} - void UnaryOpExpression::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/unary_op_expression.h b/src/ast/unary_op_expression.h index 60c97f027e..91cd8ee27a 100644 --- a/src/ast/unary_op_expression.h +++ b/src/ast/unary_op_expression.h @@ -44,9 +44,6 @@ class UnaryOpExpression : public Castable { /// @return the newly cloned node UnaryOpExpression* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/unary_op_expression_test.cc b/src/ast/unary_op_expression_test.cc index 8ac60829aa..2f1242a94a 100644 --- a/src/ast/unary_op_expression_test.cc +++ b/src/ast/unary_op_expression_test.cc @@ -14,6 +14,7 @@ #include "src/ast/unary_op_expression.h" +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -45,21 +46,13 @@ TEST_F(UnaryOpExpressionTest, IsUnaryOp) { EXPECT_TRUE(u->Is()); } -TEST_F(UnaryOpExpressionTest, IsValid) { - auto* ident = Expr("ident"); - auto* u = create(UnaryOp::kNot, ident); - EXPECT_TRUE(u->IsValid()); -} - -TEST_F(UnaryOpExpressionTest, IsValid_NullExpression) { - auto* u = create(UnaryOp::kNot, nullptr); - EXPECT_FALSE(u->IsValid()); -} - -TEST_F(UnaryOpExpressionTest, IsValid_InvalidExpression) { - auto* ident = Expr(""); - auto* u = create(UnaryOp::kNot, ident); - EXPECT_FALSE(u->IsValid()); +TEST_F(UnaryOpExpressionTest, Assert_NullExpression) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(UnaryOp::kNot, nullptr); + }, + "internal compiler error"); } TEST_F(UnaryOpExpressionTest, ToStr) { diff --git a/src/ast/variable.cc b/src/ast/variable.cc index 0af22c03cf..9606b331a6 100644 --- a/src/ast/variable.cc +++ b/src/ast/variable.cc @@ -36,7 +36,10 @@ Variable::Variable(const Source& source, is_const_(is_const), constructor_(constructor), decorations_(std::move(decorations)), - declared_storage_class_(sc) {} + declared_storage_class_(sc) { + TINT_ASSERT(symbol_.IsValid()); + TINT_ASSERT(type_); +} Variable::Variable(Variable&&) = default; @@ -79,7 +82,7 @@ LocationDecoration* Variable::GetLocationDecoration() const { } uint32_t Variable::constant_id() const { - assert(HasConstantIdDecoration()); + TINT_ASSERT(HasConstantIdDecoration()); for (auto* deco : decorations_) { if (auto* cid = deco->As()) { return cid->value(); @@ -98,19 +101,6 @@ Variable* Variable::Clone(CloneContext* ctx) const { is_const_, ctor, decos); } -bool Variable::IsValid() const { - if (!symbol_.IsValid()) { - return false; - } - if (type_ == nullptr) { - return false; - } - if (constructor_ && !constructor_->IsValid()) { - return false; - } - return true; -} - void Variable::info_to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/variable.h b/src/ast/variable.h index e5bcb0a6df..3e44dcfb9f 100644 --- a/src/ast/variable.h +++ b/src/ast/variable.h @@ -137,9 +137,6 @@ class Variable : public Castable { /// @return the newly cloned node Variable* Clone(CloneContext* ctx) const override; - /// @returns true if the variable is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/variable_decl_statement.cc b/src/ast/variable_decl_statement.cc index 61d6121ae1..9df400775f 100644 --- a/src/ast/variable_decl_statement.cc +++ b/src/ast/variable_decl_statement.cc @@ -23,7 +23,9 @@ namespace ast { VariableDeclStatement::VariableDeclStatement(const Source& source, Variable* variable) - : Base(source), variable_(variable) {} + : Base(source), variable_(variable) { + TINT_ASSERT(variable_); +} VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default; @@ -36,10 +38,6 @@ VariableDeclStatement* VariableDeclStatement::Clone(CloneContext* ctx) const { return ctx->dst->create(src, var); } -bool VariableDeclStatement::IsValid() const { - return variable_ != nullptr && variable_->IsValid(); -} - void VariableDeclStatement::to_str(const semantic::Info& sem, std::ostream& out, size_t indent) const { diff --git a/src/ast/variable_decl_statement.h b/src/ast/variable_decl_statement.h index 10de4a9d3f..698d19a071 100644 --- a/src/ast/variable_decl_statement.h +++ b/src/ast/variable_decl_statement.h @@ -42,9 +42,6 @@ class VariableDeclStatement /// @return the newly cloned node VariableDeclStatement* Clone(CloneContext* ctx) const override; - /// @returns true if the node is valid - bool IsValid() const override; - /// Writes a representation of the node to the output stream /// @param sem the semantic info for the program /// @param out the stream to write to diff --git a/src/ast/variable_decl_statement_test.cc b/src/ast/variable_decl_statement_test.cc index d3ebbb69ac..3447ca2c16 100644 --- a/src/ast/variable_decl_statement_test.cc +++ b/src/ast/variable_decl_statement_test.cc @@ -14,6 +14,7 @@ #include "src/ast/variable_decl_statement.h" +#include "gtest/gtest-spi.h" #include "src/ast/test_helper.h" namespace tint { @@ -46,21 +47,13 @@ TEST_F(VariableDeclStatementTest, IsVariableDecl) { EXPECT_TRUE(stmt->Is()); } -TEST_F(VariableDeclStatementTest, IsValid) { - auto* var = Var("a", ty.f32(), StorageClass::kNone); - auto* stmt = create(var); - EXPECT_TRUE(stmt->IsValid()); -} - -TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) { - auto* var = Var("", ty.f32(), StorageClass::kNone); - auto* stmt = create(var); - EXPECT_FALSE(stmt->IsValid()); -} - -TEST_F(VariableDeclStatementTest, IsValid_NullVariable) { - auto* stmt = create(nullptr); - EXPECT_FALSE(stmt->IsValid()); +TEST_F(VariableDeclStatementTest, Assert_NullVariable) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.create(nullptr); + }, + "internal compiler error"); } TEST_F(VariableDeclStatementTest, ToStr) { diff --git a/src/ast/variable_test.cc b/src/ast/variable_test.cc index 61760244b5..51390803f5 100644 --- a/src/ast/variable_test.cc +++ b/src/ast/variable_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/constant_id_decoration.h" #include "src/ast/test_helper.h" @@ -62,34 +63,22 @@ TEST_F(VariableTest, CreationEmpty) { EXPECT_EQ(v->source().range.end.column, 7u); } -TEST_F(VariableTest, IsValid) { - auto* v = Var("my_var", ty.i32(), StorageClass::kNone); - EXPECT_TRUE(v->IsValid()); +TEST_F(VariableTest, Assert_MissingSymbol) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Var("", b.ty.i32(), StorageClass::kNone); + }, + "internal compiler error"); } -TEST_F(VariableTest, IsValid_WithConstructor) { - auto* v = Var("my_var", ty.i32(), StorageClass::kNone, Expr("ident")); - EXPECT_TRUE(v->IsValid()); -} - -TEST_F(VariableTest, IsValid_MissingSymbol) { - auto* v = Var("", ty.i32(), StorageClass::kNone); - EXPECT_FALSE(v->IsValid()); -} - -TEST_F(VariableTest, IsValid_MissingType) { - auto* v = Var("x", nullptr, StorageClass::kNone); - EXPECT_FALSE(v->IsValid()); -} - -TEST_F(VariableTest, IsValid_MissingBoth) { - auto* v = Var("", nullptr, StorageClass::kNone); - EXPECT_FALSE(v->IsValid()); -} - -TEST_F(VariableTest, IsValid_InvalidConstructor) { - auto* v = Var("my_var", ty.i32(), StorageClass::kNone, Expr("")); - EXPECT_FALSE(v->IsValid()); +TEST_F(VariableTest, Assert_NullType) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Var("x", nullptr, StorageClass::kNone); + }, + "internal compiler error"); } TEST_F(VariableTest, to_str) { diff --git a/src/clone_context_test.cc b/src/clone_context_test.cc index 529a18bcf6..372da300a0 100644 --- a/src/clone_context_test.cc +++ b/src/clone_context_test.cc @@ -37,7 +37,6 @@ struct Node : public Castable { return out; } - bool IsValid() const override { return true; } void to_str(const semantic::Info&, std::ostream&, size_t) const override {} }; @@ -55,7 +54,6 @@ struct NotANode : public Castable { return ctx->dst->create(); } - bool IsValid() const override { return true; } void to_str(const semantic::Info&, std::ostream&, size_t) const override {} }; diff --git a/src/program_builder.cc b/src/program_builder.cc index 37e78bf9f8..c65a04470e 100644 --- a/src/program_builder.cc +++ b/src/program_builder.cc @@ -60,7 +60,7 @@ ProgramBuilder ProgramBuilder::Wrap(const Program* program) { } bool ProgramBuilder::IsValid() const { - return !diagnostics_.contains_errors() && ast_->IsValid(); + return !diagnostics_.contains_errors(); } std::string ProgramBuilder::str(const ast::Node* node) const { diff --git a/src/program_test.cc b/src/program_test.cc index daa2a70628..700923cfce 100644 --- a/src/program_test.cc +++ b/src/program_test.cc @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "gtest/gtest-spi.h" #include "src/ast/return_statement.h" #include "src/ast/test_helper.h" @@ -37,109 +38,43 @@ TEST_F(ProgramTest, ToStrEmitsPreambleAndPostamble) { EXPECT_EQ(str, expected); } -TEST_F(ProgramTest, IsValid_Empty) { +TEST_F(ProgramTest, EmptyIsValid) { Program program(std::move(*this)); EXPECT_TRUE(program.IsValid()); } -TEST_F(ProgramTest, IsValid_GlobalVariable) { +TEST_F(ProgramTest, Assert_GlobalVariable) { Global("var", ty.f32(), ast::StorageClass::kInput); Program program(std::move(*this)); EXPECT_TRUE(program.IsValid()); } -TEST_F(ProgramTest, IsValid_Null_GlobalVariable) { - AST().AddGlobalVariable(nullptr); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); +TEST_F(ProgramTest, Assert_NullGlobalVariable) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.AST().AddGlobalVariable(nullptr); + }, + "internal compiler error"); } -TEST_F(ProgramTest, IsValid_Invalid_GlobalVariable) { - Global("var", nullptr, ast::StorageClass::kInput); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); +TEST_F(ProgramTest, Assert_NullConstructedType) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.AST().AddConstructedType(nullptr); + }, + "internal compiler error"); } -TEST_F(ProgramTest, IsValid_Alias) { - auto* alias = ty.alias("alias", ty.f32()); - AST().AddConstructedType(alias); - - Program program(std::move(*this)); - EXPECT_TRUE(program.IsValid()); -} - -TEST_F(ProgramTest, IsValid_Null_Alias) { - AST().AddConstructedType(nullptr); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); -} - -TEST_F(ProgramTest, IsValid_Struct) { - auto* st = ty.struct_("name", {}); - auto* alias = ty.alias("name", st); - AST().AddConstructedType(alias); - - Program program(std::move(*this)); - EXPECT_TRUE(program.IsValid()); -} - -TEST_F(ProgramTest, IsValid_Struct_EmptyName) { - auto* st = ty.struct_("", {}); - auto* alias = ty.alias("name", st); - AST().AddConstructedType(alias); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); -} - -TEST_F(ProgramTest, IsValid_Function) { - Func("main", ast::VariableList(), ty.f32(), ast::StatementList{}, - ast::FunctionDecorationList{}); - - Program program(std::move(*this)); - EXPECT_TRUE(program.IsValid()); -} - -TEST_F(ProgramTest, IsValid_Null_Function) { - AST().AddFunction(nullptr); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); -} - -TEST_F(ProgramTest, IsValid_Invalid_Function) { - Func("main", ast::VariableList{}, nullptr, ast::StatementList{}, - ast::FunctionDecorationList{}); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); -} - -TEST_F(ProgramTest, IsValid_Invalid_UnknownVar) { - Func("main", ast::VariableList{}, nullptr, - ast::StatementList{ - create(Expr("unknown_ident")), - }, - ast::FunctionDecorationList{}); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); - EXPECT_NE(program.Diagnostics().count(), 0u); -} - -TEST_F(ProgramTest, IsValid_GeneratesError) { - AST().AddGlobalVariable(nullptr); - - Program program(std::move(*this)); - EXPECT_FALSE(program.IsValid()); - EXPECT_EQ(program.Diagnostics().count(), 1u); - EXPECT_EQ(program.Diagnostics().error_count(), 1u); - EXPECT_EQ(program.Diagnostics().begin()->message, - "invalid program generated"); +TEST_F(ProgramTest, Assert_Null_Function) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.AST().AddFunction(nullptr); + }, + "internal compiler error"); } TEST_F(ProgramTest, DiagnosticsMove) { diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc index 01e1a92674..a5bb13888e 100644 --- a/src/reader/spirv/function.cc +++ b/src/reader/spirv/function.cc @@ -684,9 +684,6 @@ DefInfo::DefInfo(const spvtools::opt::Instruction& def_inst, DefInfo::~DefInfo() = default; -bool StatementBuilder::IsValid() const { - return true; -} ast::Node* StatementBuilder::Clone(CloneContext*) const { return nullptr; } @@ -4117,6 +4114,9 @@ bool FunctionEmitter::EmitFunctionCall(const spvtools::opt::Instruction& inst) { for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) { params.emplace_back(MakeOperand(inst, iarg).expr); } + if (failed()) { + return false; + } auto* call_expr = create(Source{}, function, std::move(params)); auto* result_type = parser_impl_.ConvertType(inst.type_id()); diff --git a/src/reader/spirv/function.h b/src/reader/spirv/function.h index 086a02eab8..650d44b462 100644 --- a/src/reader/spirv/function.h +++ b/src/reader/spirv/function.h @@ -368,7 +368,6 @@ class StatementBuilder : public Castable { virtual ast::Statement* Build(ProgramBuilder* builder) const = 0; private: - bool IsValid() const override; Node* Clone(CloneContext*) const override; void to_str(const semantic::Info& sem, std::ostream& out, diff --git a/src/resolver/validation_test.cc b/src/resolver/validation_test.cc index 0366523908..49c579630e 100644 --- a/src/resolver/validation_test.cc +++ b/src/resolver/validation_test.cc @@ -50,7 +50,6 @@ class FakeStmt : public ast::Statement { public: explicit FakeStmt(Source source) : ast::Statement(source) {} FakeStmt* Clone(CloneContext*) const override { return nullptr; } - bool IsValid() const override { return true; } void to_str(const semantic::Info&, std::ostream& out, size_t) const override { out << "Fake"; } @@ -60,7 +59,6 @@ class FakeExpr : public ast::Expression { public: explicit FakeExpr(Source source) : ast::Expression(source) {} FakeExpr* Clone(CloneContext*) const override { return nullptr; } - bool IsValid() const override { return true; } void to_str(const semantic::Info&, std::ostream&, size_t) const override {} }; diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc index 8752e01e19..4a066fcf51 100644 --- a/src/writer/spirv/builder.cc +++ b/src/writer/spirv/builder.cc @@ -2715,8 +2715,10 @@ bool Builder::GenerateLoopStatement(ast::LoopStatement* stmt) { if (!GenerateLabel(continue_block_id)) { return false; } - if (!GenerateBlockStatementWithoutScoping(stmt->continuing())) { - return false; + if (stmt->has_continuing()) { + if (!GenerateBlockStatementWithoutScoping(stmt->continuing())) { + return false; + } } scope_stack_.pop_scope();