ast: Replace IsValid() with TINT_ASSERT()
The readers must not produce invalid ASTs.
If readers cannot produce a valid AST, then they should error instead.
If a reader does produce an invalid AST, this change catches this bad behavior early, significantly helping identify the root of the broken logic.
IsValid() made a bit more sense in the days where the AST was mutable, and was constructed by calling setters on the nodes to build up the tree.
In order to detect bad ASTs, IsValid() would have to perform an entire AST traversal and give a yes / no answer for the entire tree. Not only was this slow, an answer of 'no' didn't tell you *where* the AST was invalid, resulting in a lot of manual debugging.
Now that the AST is fully immutable, all child nodes need to be built before their parents. The AST node constructors now become a perfect place to perform pointer sanity checking.
The argument for attempting to catch and handle invalid ASTs is not a compelling one.
Invalid ASTs are invalid compiler behavior, not something that should ever happen with a correctly functioning compiler.
If this were to happen in production, the user would be utterly clueless to _why_ the program is invalid, or _how_ to fix it.
Attempting to handle invalid ASTs is just masking a much larger problem.
Let's just let the fuzzers do their job to catch any of these cases early.
Fixed: chromium:1185569
Change-Id: I6496426a3a9da9d42627d2c1ca23917bfd04cc5c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/44048
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/ast/array_accessor_expression.cc b/src/ast/array_accessor_expression.cc
index 934055e..5424a98 100644
--- a/src/ast/array_accessor_expression.cc
+++ b/src/ast/array_accessor_expression.cc
@@ -24,7 +24,10 @@
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 @@
return ctx->dst->create<ArrayAccessorExpression>(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 f6e8f1e..24a13ec 100644
--- a/src/ast/array_accessor_expression.h
+++ b/src/ast/array_accessor_expression.h
@@ -47,9 +47,6 @@
/// @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 671ec98..154cc69 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 @@
EXPECT_TRUE(exp->Is<ArrayAccessorExpression>());
}
-TEST_F(ArrayAccessorExpressionTest, IsValid) {
- auto* ary = Expr("ary");
- auto* idx = Expr("idx");
-
- auto* exp = create<ArrayAccessorExpression>(ary, idx);
- EXPECT_TRUE(exp->IsValid());
+TEST_F(ArrayAccessorExpressionTest, Assert_NullArray) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<ArrayAccessorExpression>(nullptr, b.Expr("idx"));
+ },
+ "internal compiler error");
}
-TEST_F(ArrayAccessorExpressionTest, IsValid_MissingArray) {
- auto* idx = Expr("idx");
-
- auto* exp = create<ArrayAccessorExpression>(nullptr, idx);
- EXPECT_FALSE(exp->IsValid());
-}
-
-TEST_F(ArrayAccessorExpressionTest, IsValid_MissingIndex) {
- auto* ary = Expr("ary");
-
- auto* exp = create<ArrayAccessorExpression>(ary, nullptr);
- EXPECT_FALSE(exp->IsValid());
-}
-
-TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidArray) {
- auto* ary = Expr("");
- auto* idx = Expr("idx");
- auto* exp = create<ArrayAccessorExpression>(ary, idx);
- EXPECT_FALSE(exp->IsValid());
-}
-
-TEST_F(ArrayAccessorExpressionTest, IsValid_InvalidIndex) {
- auto* ary = Expr("ary");
- auto* idx = Expr("");
- auto* exp = create<ArrayAccessorExpression>(ary, idx);
- EXPECT_FALSE(exp->IsValid());
+TEST_F(ArrayAccessorExpressionTest, Assert_NullIndex) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<ArrayAccessorExpression>(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 3230499..8e98c23 100644
--- a/src/ast/assignment_statement.cc
+++ b/src/ast/assignment_statement.cc
@@ -24,7 +24,10 @@
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 @@
return ctx->dst->create<AssignmentStatement>(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 4368ee7..a7a0365 100644
--- a/src/ast/assignment_statement.h
+++ b/src/ast/assignment_statement.h
@@ -44,9 +44,6 @@
/// @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 3a0234f..9ac7882 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 @@
EXPECT_TRUE(stmt->Is<AssignmentStatement>());
}
-TEST_F(AssignmentStatementTest, IsValid) {
- auto* lhs = Expr("lhs");
- auto* rhs = Expr("rhs");
-
- auto* stmt = create<AssignmentStatement>(lhs, rhs);
- EXPECT_TRUE(stmt->IsValid());
+TEST_F(AssignmentStatementTest, Assert_NullLHS) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<AssignmentStatement>(nullptr, b.Expr(1));
+ },
+ "internal compiler error");
}
-TEST_F(AssignmentStatementTest, IsValid_MissingLHS) {
- auto* rhs = Expr("rhs");
-
- auto* stmt = create<AssignmentStatement>(nullptr, rhs);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(AssignmentStatementTest, IsValid_MissingRHS) {
- auto* lhs = Expr("lhs");
-
- auto* stmt = create<AssignmentStatement>(lhs, nullptr);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(AssignmentStatementTest, IsValid_InvalidLHS) {
- auto* lhs = Expr("");
- auto* rhs = Expr("rhs");
- auto* stmt = create<AssignmentStatement>(lhs, rhs);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(AssignmentStatementTest, IsValid_InvalidRHS) {
- auto* lhs = Expr("lhs");
- auto* rhs = Expr("");
- auto* stmt = create<AssignmentStatement>(lhs, rhs);
- EXPECT_FALSE(stmt->IsValid());
+TEST_F(AssignmentStatementTest, Assert_NullRHS) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<AssignmentStatement>(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 83fbaac..2426eb9 100644
--- a/src/ast/binary_expression.cc
+++ b/src/ast/binary_expression.cc
@@ -25,7 +25,11 @@
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 @@
return ctx->dst->create<BinaryExpression>(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 036eb5a..84834ac 100644
--- a/src/ast/binary_expression.h
+++ b/src/ast/binary_expression.h
@@ -110,9 +110,6 @@
/// @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 045231e..8109e41 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 @@
EXPECT_TRUE(r->Is<BinaryExpression>());
}
-TEST_F(BinaryExpressionTest, IsValid) {
- auto* lhs = Expr("lhs");
- auto* rhs = Expr("rhs");
-
- auto* r = create<BinaryExpression>(BinaryOp::kEqual, lhs, rhs);
- EXPECT_TRUE(r->IsValid());
-}
-
TEST_F(BinaryExpressionTest, IsValid_Null_LHS) {
- auto* rhs = Expr("rhs");
-
- auto* r = create<BinaryExpression>(BinaryOp::kEqual, nullptr, rhs);
- EXPECT_FALSE(r->IsValid());
-}
-
-TEST_F(BinaryExpressionTest, IsValid_Invalid_LHS) {
- auto* lhs = Expr("");
- auto* rhs = Expr("rhs");
-
- auto* r = create<BinaryExpression>(BinaryOp::kEqual, lhs, rhs);
- EXPECT_FALSE(r->IsValid());
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<BinaryExpression>(BinaryOp::kEqual, nullptr, b.Expr("rhs"));
+ },
+ "internal compiler error");
}
TEST_F(BinaryExpressionTest, IsValid_Null_RHS) {
- auto* lhs = Expr("lhs");
-
- auto* r = create<BinaryExpression>(BinaryOp::kEqual, lhs, nullptr);
- EXPECT_FALSE(r->IsValid());
-}
-
-TEST_F(BinaryExpressionTest, IsValid_Invalid_RHS) {
- auto* lhs = Expr("lhs");
- auto* rhs = Expr("");
-
- auto* r = create<BinaryExpression>(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<BinaryExpression>(BinaryOp::kNone, lhs, rhs);
- EXPECT_FALSE(r->IsValid());
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<BinaryExpression>(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 2b985f7..9d73fe4 100644
--- a/src/ast/bitcast_expression.cc
+++ b/src/ast/bitcast_expression.cc
@@ -24,7 +24,10 @@
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 @@
return ctx->dst->create<BitcastExpression>(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 d56dec8..0e83b91 100644
--- a/src/ast/bitcast_expression.h
+++ b/src/ast/bitcast_expression.h
@@ -43,9 +43,6 @@
/// @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 3f2cc7c..754fa36 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 @@
EXPECT_TRUE(exp->Is<BitcastExpression>());
}
-TEST_F(BitcastExpressionTest, IsValid) {
- auto* expr = Expr("expr");
-
- auto* exp = create<BitcastExpression>(ty.f32(), expr);
- EXPECT_TRUE(exp->IsValid());
+TEST_F(BitcastExpressionTest, Assert_NullType) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<BitcastExpression>(nullptr, b.Expr("idx"));
+ },
+ "internal compiler error");
}
-TEST_F(BitcastExpressionTest, IsValid_MissingType) {
- auto* expr = Expr("expr");
-
- auto* exp = create<BitcastExpression>(nullptr, expr);
- EXPECT_FALSE(exp->IsValid());
-}
-
-TEST_F(BitcastExpressionTest, IsValid_MissingExpr) {
- auto* exp = create<BitcastExpression>(ty.f32(), nullptr);
- EXPECT_FALSE(exp->IsValid());
-}
-
-TEST_F(BitcastExpressionTest, IsValid_InvalidExpr) {
- auto* expr = Expr("");
- auto* e = create<BitcastExpression>(ty.f32(), expr);
- EXPECT_FALSE(e->IsValid());
+TEST_F(BitcastExpressionTest, Assert_NullExpr) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<BitcastExpression>(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 5ed4d04..d2cdd93 100644
--- a/src/ast/block_statement.cc
+++ b/src/ast/block_statement.cc
@@ -23,7 +23,11 @@
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 @@
return ctx->dst->create<BlockStatement>(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 f5653f9..103c8c4 100644
--- a/src/ast/block_statement.h
+++ b/src/ast/block_statement.h
@@ -71,9 +71,6 @@
/// @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 c4a583c..4a5b2dd 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 @@
EXPECT_TRUE(b->Is<BlockStatement>());
}
-TEST_F(BlockStatementTest, IsValid) {
- auto* b = create<BlockStatement>(ast::StatementList{
- create<DiscardStatement>(),
- });
- EXPECT_TRUE(b->IsValid());
-}
-
-TEST_F(BlockStatementTest, IsValid_Empty) {
- auto* b = create<BlockStatement>(ast::StatementList{});
- EXPECT_TRUE(b->IsValid());
-}
-
-TEST_F(BlockStatementTest, IsValid_NullBodyStatement) {
- auto* b = create<BlockStatement>(ast::StatementList{
- create<DiscardStatement>(),
- nullptr,
- });
-
- EXPECT_FALSE(b->IsValid());
-}
-
-TEST_F(BlockStatementTest, IsValid_InvalidBodyStatement) {
- auto* b = create<BlockStatement>(
-
- ast::StatementList{
- create<IfStatement>(nullptr, create<BlockStatement>(StatementList{}),
- ElseStatementList{}),
- });
- EXPECT_FALSE(b->IsValid());
+TEST_F(BlockStatementTest, Assert_NullStatement) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<BlockStatement>(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 9ec4e34..0824c66 100644
--- a/src/ast/break_statement.cc
+++ b/src/ast/break_statement.cc
@@ -33,10 +33,6 @@
return ctx->dst->create<BreakStatement>(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 271b1ff..1bc6148 100644
--- a/src/ast/break_statement.h
+++ b/src/ast/break_statement.h
@@ -36,9 +36,6 @@
/// @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 78a0cf8..236f151 100644
--- a/src/ast/break_statement_test.cc
+++ b/src/ast/break_statement_test.cc
@@ -34,11 +34,6 @@
EXPECT_TRUE(stmt->Is<BreakStatement>());
}
-TEST_F(BreakStatementTest, IsValid) {
- auto* stmt = create<BreakStatement>();
- EXPECT_TRUE(stmt->IsValid());
-}
-
TEST_F(BreakStatementTest, ToStr) {
auto* stmt = create<BreakStatement>();
EXPECT_EQ(str(stmt), R"(Break{}
diff --git a/src/ast/call_expression.cc b/src/ast/call_expression.cc
index 628dae6..e58396b 100644
--- a/src/ast/call_expression.cc
+++ b/src/ast/call_expression.cc
@@ -24,7 +24,12 @@
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 @@
return ctx->dst->create<CallExpression>(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 b503d03..f317a60 100644
--- a/src/ast/call_expression.h
+++ b/src/ast/call_expression.h
@@ -43,9 +43,6 @@
/// @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 e02d6bb..4040153 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 @@
EXPECT_TRUE(stmt->Is<CallExpression>());
}
-TEST_F(CallExpressionTest, IsValid) {
- auto* func = Expr("func");
- auto* stmt = create<CallExpression>(func, ExpressionList{});
- EXPECT_TRUE(stmt->IsValid());
+TEST_F(CallExpressionTest, Assert_NullFunction) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<CallExpression>(nullptr, ExpressionList{});
+ },
+ "internal compiler error");
}
-TEST_F(CallExpressionTest, IsValid_MissingFunction) {
- auto* stmt = create<CallExpression>(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<CallExpression>(func, params);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(CallExpressionTest, IsValid_InvalidFunction) {
- auto* func = Expr("");
- ExpressionList params;
- params.push_back(Expr("param1"));
-
- auto* stmt = create<CallExpression>(func, params);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(CallExpressionTest, IsValid_InvalidParam) {
- auto* func = Expr("func");
- ExpressionList params;
- params.push_back(Expr(""));
-
- auto* stmt = create<CallExpression>(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<CallExpression>(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 16ecfb1..5b52a44 100644
--- a/src/ast/call_statement.cc
+++ b/src/ast/call_statement.cc
@@ -22,7 +22,9 @@
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 @@
return ctx->dst->create<CallStatement>(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 dd2c837..5c948a8 100644
--- a/src/ast/call_statement.h
+++ b/src/ast/call_statement.h
@@ -41,9 +41,6 @@
/// @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 2736463..092dc54 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, IsCall) {
- auto* c = create<CallStatement>(nullptr);
+ auto* c = create<CallStatement>(Call("f"));
EXPECT_TRUE(c->Is<CallStatement>());
}
-TEST_F(CallStatementTest, IsValid) {
- auto* c = create<CallStatement>(
- create<CallExpression>(Expr("func"), ExpressionList{}));
- EXPECT_TRUE(c->IsValid());
-}
-
-TEST_F(CallStatementTest, IsValid_MissingExpr) {
- auto* c = create<CallStatement>(nullptr);
- EXPECT_FALSE(c->IsValid());
-}
-
-TEST_F(CallStatementTest, IsValid_InvalidExpr) {
- auto* c = create<CallStatement>(
- create<CallExpression>(nullptr, ast::ExpressionList{}));
- EXPECT_FALSE(c->IsValid());
+TEST_F(CallStatementTest, Assert_NullCall) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<CallStatement>(nullptr);
+ },
+ "internal compiler error");
}
TEST_F(CallStatementTest, ToStr) {
diff --git a/src/ast/case_statement.cc b/src/ast/case_statement.cc
index 5f4dc37..e95383c 100644
--- a/src/ast/case_statement.cc
+++ b/src/ast/case_statement.cc
@@ -24,7 +24,9 @@
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 @@
return ctx->dst->create<CaseStatement>(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 ef9c1ff..6a61837 100644
--- a/src/ast/case_statement.h
+++ b/src/ast/case_statement.h
@@ -56,9 +56,6 @@
/// @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 2f9c74c..6e64f39 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 @@
EXPECT_TRUE(c->Is<CaseStatement>());
}
-TEST_F(CaseStatementTest, IsValid) {
- auto* c = create<CaseStatement>(CaseSelectorList{},
- create<BlockStatement>(StatementList{}));
- EXPECT_TRUE(c->IsValid());
-}
-
-TEST_F(CaseStatementTest, IsValid_NullBodyStatement) {
- CaseSelectorList b;
- b.push_back(create<SintLiteral>(ty.i32(), 2));
-
- auto* body = create<BlockStatement>(StatementList{
- create<DiscardStatement>(),
- nullptr,
- });
- auto* c = create<CaseStatement>(b, body);
- EXPECT_FALSE(c->IsValid());
-}
-
-TEST_F(CaseStatementTest, IsValid_InvalidBodyStatement) {
- CaseSelectorList b;
- b.push_back(create<SintLiteral>(ty.i32(), 2));
-
- auto* body = create<BlockStatement>(
-
- StatementList{
- create<IfStatement>(nullptr, create<BlockStatement>(StatementList{}),
- ElseStatementList{}),
- });
- auto* c = create<CaseStatement>(CaseSelectorList{b}, body);
- EXPECT_FALSE(c->IsValid());
+TEST_F(CaseStatementTest, Assert_NullBody) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<CaseStatement>(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 f5d5201..64f2267 100644
--- a/src/ast/continue_statement.cc
+++ b/src/ast/continue_statement.cc
@@ -33,10 +33,6 @@
return ctx->dst->create<ContinueStatement>(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 512741f..f2be33a 100644
--- a/src/ast/continue_statement.h
+++ b/src/ast/continue_statement.h
@@ -36,9 +36,6 @@
/// @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 356011e..dd3fd94 100644
--- a/src/ast/continue_statement_test.cc
+++ b/src/ast/continue_statement_test.cc
@@ -34,11 +34,6 @@
EXPECT_TRUE(stmt->Is<ContinueStatement>());
}
-TEST_F(ContinueStatementTest, IsValid) {
- auto* stmt = create<ContinueStatement>();
- EXPECT_TRUE(stmt->IsValid());
-}
-
TEST_F(ContinueStatementTest, ToStr) {
auto* stmt = create<ContinueStatement>();
EXPECT_EQ(str(stmt), R"(Continue{}
diff --git a/src/ast/decoration.cc b/src/ast/decoration.cc
index c7573f4..447105f 100644
--- a/src/ast/decoration.cc
+++ b/src/ast/decoration.cc
@@ -39,9 +39,5 @@
return out << "<unknown>";
}
-bool Decoration::IsValid() const {
- return true;
-}
-
} // namespace ast
} // namespace tint
diff --git a/src/ast/decoration.h b/src/ast/decoration.h
index 378ad7e..32b1e60 100644
--- a/src/ast/decoration.h
+++ b/src/ast/decoration.h
@@ -42,9 +42,6 @@
/// @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 a33373f..c31ed8d 100644
--- a/src/ast/discard_statement.cc
+++ b/src/ast/discard_statement.cc
@@ -33,10 +33,6 @@
return ctx->dst->create<DiscardStatement>(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 14e96e4..c2c6bb9 100644
--- a/src/ast/discard_statement.h
+++ b/src/ast/discard_statement.h
@@ -36,9 +36,6 @@
/// @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 8033abe..dc79806 100644
--- a/src/ast/discard_statement_test.cc
+++ b/src/ast/discard_statement_test.cc
@@ -44,11 +44,6 @@
EXPECT_TRUE(stmt->Is<DiscardStatement>());
}
-TEST_F(DiscardStatementTest, IsValid) {
- auto* stmt = create<DiscardStatement>();
- EXPECT_TRUE(stmt->IsValid());
-}
-
TEST_F(DiscardStatementTest, ToStr) {
auto* stmt = create<DiscardStatement>();
EXPECT_EQ(str(stmt), R"(Discard{}
diff --git a/src/ast/else_statement.cc b/src/ast/else_statement.cc
index aa359e5..6706247 100644
--- a/src/ast/else_statement.cc
+++ b/src/ast/else_statement.cc
@@ -24,7 +24,9 @@
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 @@
return ctx->dst->create<ElseStatement>(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 9e34019..a2c07c3 100644
--- a/src/ast/else_statement.h
+++ b/src/ast/else_statement.h
@@ -53,9 +53,6 @@
/// @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 e17e599..175b09c 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_WithSource) {
- auto* e = create<ElseStatement>(Source{Source::Location{20, 2}}, nullptr,
+ auto* e = create<ElseStatement>(Source{Source::Location{20, 2}}, Expr(true),
create<BlockStatement>(StatementList{}));
auto src = e->source();
EXPECT_EQ(src.range.begin.line, 20u);
@@ -62,45 +63,13 @@
EXPECT_FALSE(e->HasCondition());
}
-TEST_F(ElseStatementTest, IsValid) {
- auto* e =
- create<ElseStatement>(nullptr, create<BlockStatement>(StatementList{}));
- EXPECT_TRUE(e->IsValid());
-}
-
-TEST_F(ElseStatementTest, IsValid_WithBody) {
- auto* body = create<BlockStatement>(StatementList{
- create<DiscardStatement>(),
- });
- auto* e = create<ElseStatement>(nullptr, body);
- EXPECT_TRUE(e->IsValid());
-}
-
-TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) {
- auto* body = create<BlockStatement>(StatementList{
- create<DiscardStatement>(),
- nullptr,
- });
- auto* e = create<ElseStatement>(nullptr, body);
- EXPECT_FALSE(e->IsValid());
-}
-
-TEST_F(ElseStatementTest, IsValid_InvalidCondition) {
- auto* cond = create<ScalarConstructorExpression>(nullptr);
- auto* e =
- create<ElseStatement>(cond, create<BlockStatement>(StatementList{}));
- EXPECT_FALSE(e->IsValid());
-}
-
-TEST_F(ElseStatementTest, IsValid_InvalidBodyStatement) {
- auto* body = create<BlockStatement>(
-
- StatementList{
- create<IfStatement>(nullptr, create<BlockStatement>(StatementList{}),
- ElseStatementList{}),
- });
- auto* e = create<ElseStatement>(nullptr, body);
- EXPECT_FALSE(e->IsValid());
+TEST_F(ElseStatementTest, Assert_NullBody) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<ElseStatement>(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 1dcf72d..d432212 100644
--- a/src/ast/fallthrough_statement.cc
+++ b/src/ast/fallthrough_statement.cc
@@ -34,10 +34,6 @@
return ctx->dst->create<FallthroughStatement>(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 b0d14b0..cb586a0 100644
--- a/src/ast/fallthrough_statement.h
+++ b/src/ast/fallthrough_statement.h
@@ -36,9 +36,6 @@
/// @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 8072e1c..047af88 100644
--- a/src/ast/fallthrough_statement_test.cc
+++ b/src/ast/fallthrough_statement_test.cc
@@ -42,11 +42,6 @@
EXPECT_TRUE(stmt->Is<FallthroughStatement>());
}
-TEST_F(FallthroughStatementTest, IsValid) {
- auto* stmt = create<FallthroughStatement>();
- EXPECT_TRUE(stmt->IsValid());
-}
-
TEST_F(FallthroughStatementTest, ToStr) {
auto* stmt = create<FallthroughStatement>();
EXPECT_EQ(str(stmt), R"(Fallthrough{}
diff --git a/src/ast/function.cc b/src/ast/function.cc
index 5858867..8f47a1b 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -34,7 +34,14 @@
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 @@
return ctx->dst->create<Function>(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 8ac517e..109c5df 100644
--- a/src/ast/function.h
+++ b/src/ast/function.h
@@ -89,9 +89,6 @@
/// @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 db7aee9..39a478d 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 @@
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<DiscardStatement>(),
- },
- 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<DiscardStatement>(),
- 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<DiscardStatement>(),
- 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 1f8c671..e996bac 100644
--- a/src/ast/identifier_expression.cc
+++ b/src/ast/identifier_expression.cc
@@ -22,7 +22,9 @@
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 @@
return ctx->dst->create<IdentifierExpression>(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 2794599..396ad33 100644
--- a/src/ast/identifier_expression.h
+++ b/src/ast/identifier_expression.h
@@ -41,9 +41,6 @@
/// @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 3d22e1d..cea616d 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 @@
EXPECT_TRUE(i->Is<IdentifierExpression>());
}
-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 eee9e09..7a515db 100644
--- a/src/ast/if_statement.cc
+++ b/src/ast/if_statement.cc
@@ -28,7 +28,13 @@
: 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 @@
return ctx->dst->create<IfStatement>(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 4c578aa..cf2f09a 100644
--- a/src/ast/if_statement.h
+++ b/src/ast/if_statement.h
@@ -57,9 +57,6 @@
/// @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 a222886..dcc3342 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, IsIf) {
auto* stmt = create<IfStatement>(
- nullptr, create<BlockStatement>(StatementList{}), ElseStatementList{});
+ Expr(true), create<BlockStatement>(StatementList{}), ElseStatementList{});
EXPECT_TRUE(stmt->Is<IfStatement>());
}
-TEST_F(IfStatementTest, IsValid) {
- auto* cond = Expr("cond");
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(cond, body, ElseStatementList{});
- EXPECT_TRUE(stmt->IsValid());
+TEST_F(IfStatementTest, Assert_NullCondition) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ auto* body = b.create<BlockStatement>(StatementList{});
+ b.create<IfStatement>(nullptr, body, ElseStatementList{});
+ },
+ "internal compiler error");
}
-TEST_F(IfStatementTest, IsValid_WithElseStatements) {
- auto* cond = Expr("cond");
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(
- cond, body,
- ElseStatementList{
- create<ElseStatement>(Expr("Ident"),
- create<BlockStatement>(StatementList{})),
- create<ElseStatement>(nullptr,
- create<BlockStatement>(StatementList{})),
- });
- EXPECT_TRUE(stmt->IsValid());
+TEST_F(IfStatementTest, Assert_NullBody) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<IfStatement>(b.Expr(true), nullptr, ElseStatementList{});
+ },
+ "internal compiler error");
}
-TEST_F(IfStatementTest, IsValid_MissingCondition) {
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(nullptr, body, ElseStatementList{});
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(IfStatementTest, IsValid_InvalidCondition) {
- auto* cond = Expr("");
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(cond, body, ElseStatementList{});
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(IfStatementTest, IsValid_NullBodyStatement) {
- auto* cond = Expr("cond");
- auto* body = create<BlockStatement>(StatementList{
- create<DiscardStatement>(),
- nullptr,
- });
- auto* stmt = create<IfStatement>(cond, body, ElseStatementList{});
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) {
- auto* cond = Expr("cond");
- auto* body = create<BlockStatement>(
-
- StatementList{
- create<DiscardStatement>(),
- create<IfStatement>(nullptr, create<BlockStatement>(StatementList{}),
- ast::ElseStatementList{}),
- });
- auto* stmt = create<IfStatement>(cond, body, ElseStatementList{});
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(IfStatementTest, IsValid_NullElseStatement) {
- auto* cond = Expr("cond");
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(
- cond, body,
- ElseStatementList{
- create<ElseStatement>(Expr("Ident"),
- create<BlockStatement>(StatementList{})),
- create<ElseStatement>(nullptr,
- create<BlockStatement>(StatementList{})),
- nullptr,
- });
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(IfStatementTest, IsValid_InvalidElseStatement) {
- auto* cond = Expr("cond");
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(
- cond, body,
- ElseStatementList{
- create<ElseStatement>(Expr(""),
- create<BlockStatement>(StatementList{})),
- });
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) {
- auto* cond = Expr("cond");
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(
- cond, body,
- ElseStatementList{
- create<ElseStatement>(nullptr,
- create<BlockStatement>(StatementList{})),
- create<ElseStatement>(nullptr,
- create<BlockStatement>(StatementList{})),
- });
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(IfStatementTest, IsValid_ElseNotLast) {
- auto* cond = Expr("cond");
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
- auto* stmt = create<IfStatement>(
- cond, body,
- ElseStatementList{
- create<ElseStatement>(nullptr,
- create<BlockStatement>(StatementList{})),
- create<ElseStatement>(Expr("Ident"),
- create<BlockStatement>(StatementList{})),
- });
- EXPECT_FALSE(stmt->IsValid());
+TEST_F(IfStatementTest, Assert_NullElseStatement) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ auto* body = b.create<BlockStatement>(StatementList{});
+ b.create<IfStatement>(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 f6a9ceb..3d1b063 100644
--- a/src/ast/literal.cc
+++ b/src/ast/literal.cc
@@ -24,10 +24,6 @@
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 826c0bc..70039c9 100644
--- a/src/ast/literal.h
+++ b/src/ast/literal.h
@@ -30,9 +30,6 @@
/// @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 66774a8..962db02 100644
--- a/src/ast/loop_statement.cc
+++ b/src/ast/loop_statement.cc
@@ -24,7 +24,9 @@
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 @@
return ctx->dst->create<LoopStatement>(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 c0bc2dc..f2ee7ad 100644
--- a/src/ast/loop_statement.h
+++ b/src/ast/loop_statement.h
@@ -54,9 +54,6 @@
/// @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 7577773..f1e42b1 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 @@
EXPECT_TRUE(l->has_continuing());
}
-TEST_F(LoopStatementTest, IsValid) {
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
-
- auto* continuing =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
-
- auto* l = create<LoopStatement>(body, continuing);
- EXPECT_TRUE(l->IsValid());
-}
-
-TEST_F(LoopStatementTest, IsValid_WithoutContinuing) {
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
-
- auto* l =
- create<LoopStatement>(body, create<BlockStatement>(StatementList{}));
- EXPECT_TRUE(l->IsValid());
-}
-
-TEST_F(LoopStatementTest, IsValid_WithoutBody) {
- auto* l = create<LoopStatement>(create<BlockStatement>(StatementList{}),
- create<BlockStatement>(StatementList{}));
- EXPECT_TRUE(l->IsValid());
-}
-
-TEST_F(LoopStatementTest, IsValid_NullBodyStatement) {
- auto* body = create<BlockStatement>(StatementList{
- create<DiscardStatement>(),
- nullptr,
- });
-
- auto* continuing =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
-
- auto* l = create<LoopStatement>(body, continuing);
- EXPECT_FALSE(l->IsValid());
-}
-
-TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) {
- auto* body = create<BlockStatement>(
-
- StatementList{
- create<DiscardStatement>(),
- create<IfStatement>(nullptr, create<BlockStatement>(StatementList{}),
- ElseStatementList{}),
- });
-
- auto* continuing =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
-
- auto* l = create<LoopStatement>(body, continuing);
- EXPECT_FALSE(l->IsValid());
-}
-
-TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) {
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
-
- auto* continuing = create<BlockStatement>(StatementList{
- create<DiscardStatement>(),
- nullptr,
- });
-
- auto* l = create<LoopStatement>(body, continuing);
- EXPECT_FALSE(l->IsValid());
-}
-
-TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) {
- auto* body =
- create<BlockStatement>(StatementList{create<DiscardStatement>()});
-
- auto* continuing = create<BlockStatement>(
-
- StatementList{
- create<DiscardStatement>(),
- create<IfStatement>(nullptr, create<BlockStatement>(StatementList{}),
- ElseStatementList{}),
- });
-
- auto* l = create<LoopStatement>(body, continuing);
- EXPECT_FALSE(l->IsValid());
+TEST_F(LoopStatementTest, Assert_NullBody) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<LoopStatement>(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 7ad6707..6e8e9a9 100644
--- a/src/ast/member_accessor_expression.cc
+++ b/src/ast/member_accessor_expression.cc
@@ -24,7 +24,10 @@
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 @@
return ctx->dst->create<MemberAccessorExpression>(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 b3a87ab..ac2c8bf 100644
--- a/src/ast/member_accessor_expression.h
+++ b/src/ast/member_accessor_expression.h
@@ -46,9 +46,6 @@
/// @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 06f004f..44c30d1 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 @@
EXPECT_TRUE(stmt->Is<MemberAccessorExpression>());
}
-TEST_F(MemberAccessorExpressionTest, IsValid) {
- auto* stmt =
- create<MemberAccessorExpression>(Expr("structure"), Expr("member"));
- EXPECT_TRUE(stmt->IsValid());
+TEST_F(MemberAccessorExpressionTest, Assert_NullStruct) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<MemberAccessorExpression>(nullptr, b.Expr("member"));
+ },
+ "internal compiler error");
}
-TEST_F(MemberAccessorExpressionTest, IsValid_NullStruct) {
- auto* stmt = create<MemberAccessorExpression>(nullptr, Expr("member"));
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(MemberAccessorExpressionTest, IsValid_InvalidStruct) {
- auto* stmt = create<MemberAccessorExpression>(Expr(""), Expr("member"));
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(MemberAccessorExpressionTest, IsValid_NullMember) {
- auto* stmt = create<MemberAccessorExpression>(Expr("structure"), nullptr);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(MemberAccessorExpressionTest, IsValid_InvalidMember) {
- auto* stmt = create<MemberAccessorExpression>(Expr("structure"), Expr(""));
- EXPECT_FALSE(stmt->IsValid());
+TEST_F(MemberAccessorExpressionTest, Assert_NullMember) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<MemberAccessorExpression>(b.Expr("struct"), nullptr);
+ },
+ "internal compiler error");
}
TEST_F(MemberAccessorExpressionTest, ToStr) {
diff --git a/src/ast/module.cc b/src/ast/module.cc
index ed23908..892bcce 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -47,46 +47,6 @@
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<type::Alias>()) {
- if (alias->type() == nullptr) {
- return false;
- }
- if (auto* str = alias->type()->As<type::Struct>()) {
- if (!str->symbol().IsValid()) {
- return false;
- }
- }
- } else if (auto* str = ty->As<type::Struct>()) {
- 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<Module>();
out->Copy(ctx, this);
diff --git a/src/ast/module.h b/src/ast/module.h
index 91a4f87..0f518e1 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -48,6 +48,7 @@
/// 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 @@
/// 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 @@
/// 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 @@
/// @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 b77435f..ff3288e 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 @@
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 fad460f..157f93e 100644
--- a/src/ast/node.h
+++ b/src/ast/node.h
@@ -40,9 +40,6 @@
/// @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 38df855..7c5e3a1 100644
--- a/src/ast/return_statement.cc
+++ b/src/ast/return_statement.cc
@@ -38,13 +38,6 @@
return ctx->dst->create<ReturnStatement>(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 0079248..77f4805 100644
--- a/src/ast/return_statement.h
+++ b/src/ast/return_statement.h
@@ -46,9 +46,6 @@
/// @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 81fd712..d55e360 100644
--- a/src/ast/return_statement_test.cc
+++ b/src/ast/return_statement_test.cc
@@ -52,23 +52,6 @@
EXPECT_TRUE(r->has_value());
}
-TEST_F(ReturnStatementTest, IsValid_WithoutValue) {
- auto* r = create<ReturnStatement>();
- EXPECT_TRUE(r->IsValid());
-}
-
-TEST_F(ReturnStatementTest, IsValid_WithValue) {
- auto* expr = Expr("expr");
- auto* r = create<ReturnStatement>(expr);
- EXPECT_TRUE(r->IsValid());
-}
-
-TEST_F(ReturnStatementTest, IsValid_InvalidValue) {
- auto* expr = Expr("");
- auto* r = create<ReturnStatement>(expr);
- EXPECT_FALSE(r->IsValid());
-}
-
TEST_F(ReturnStatementTest, ToStr_WithValue) {
auto* expr = Expr("expr");
auto* r = create<ReturnStatement>(expr);
diff --git a/src/ast/scalar_constructor_expression.cc b/src/ast/scalar_constructor_expression.cc
index e82c17c..4f0ecce 100644
--- a/src/ast/scalar_constructor_expression.cc
+++ b/src/ast/scalar_constructor_expression.cc
@@ -22,8 +22,10 @@
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 @@
return ctx->dst->create<ScalarConstructorExpression>(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 fe6c6d9..3b56357 100644
--- a/src/ast/scalar_constructor_expression.h
+++ b/src/ast/scalar_constructor_expression.h
@@ -42,9 +42,6 @@
/// @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 aadc5be..7d82638 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 @@
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<ScalarConstructorExpression>(nullptr);
- EXPECT_FALSE(c->IsValid());
+TEST_F(ScalarConstructorExpressionTest, Assert_NullLiteral) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<ScalarConstructorExpression>(nullptr);
+ },
+ "internal compiler error");
}
TEST_F(ScalarConstructorExpressionTest, ToStr) {
diff --git a/src/ast/struct.cc b/src/ast/struct.cc
index c21c17e..6604399 100644
--- a/src/ast/struct.cc
+++ b/src/ast/struct.cc
@@ -27,7 +27,14 @@
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 @@
return ctx->dst->create<Struct>(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 752ea05..58f165f 100644
--- a/src/ast/struct.h
+++ b/src/ast/struct.h
@@ -58,9 +58,6 @@
/// @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 f6146c1..4a3a18a 100644
--- a/src/ast/struct_member.cc
+++ b/src/ast/struct_member.cc
@@ -28,7 +28,13 @@
: 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 @@
return ctx->dst->create<StructMember>(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 92491e5..0595b34 100644
--- a/src/ast/struct_member.h
+++ b/src/ast/struct_member.h
@@ -59,9 +59,6 @@
/// @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 1b835de..17c4425 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 @@
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 f2bd221..421c50f 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 @@
EXPECT_EQ(s->source().range.end.column, 8u);
}
-TEST_F(StructTest, IsValid) {
- auto* s = create<Struct>(StructMemberList{}, StructDecorationList{});
- EXPECT_TRUE(s->IsValid());
+TEST_F(StructTest, Assert_Null_StructMember) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<Struct>(StructMemberList{b.Member("a", b.ty.i32()), nullptr},
+ StructDecorationList{});
+ },
+ "internal compiler error");
}
-TEST_F(StructTest, IsValid_Null_StructMember) {
- auto* s = create<Struct>(StructMemberList{Member("a", ty.i32()), nullptr},
- StructDecorationList{});
- EXPECT_FALSE(s->IsValid());
-}
-
-TEST_F(StructTest, IsValid_Invalid_StructMember) {
- auto* s = create<Struct>(StructMemberList{Member("", ty.i32())},
- ast::StructDecorationList{});
- EXPECT_FALSE(s->IsValid());
+TEST_F(StructTest, Assert_Null_Decoration) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<Struct>(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 e196878..c413dd2 100644
--- a/src/ast/switch_statement.cc
+++ b/src/ast/switch_statement.cc
@@ -24,7 +24,12 @@
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 @@
return ctx->dst->create<SwitchStatement>(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 d3d061d..0f78635 100644
--- a/src/ast/switch_statement.h
+++ b/src/ast/switch_statement.h
@@ -49,9 +49,6 @@
/// @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 036cb8c..4373c2d 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 @@
EXPECT_TRUE(stmt->Is<SwitchStatement>());
}
-TEST_F(SwitchStatementTest, IsValid) {
- CaseSelectorList lit;
- lit.push_back(create<SintLiteral>(ty.i32(), 2));
-
- auto* ident = Expr("ident");
- CaseStatementList body;
- body.push_back(
- create<CaseStatement>(lit, create<BlockStatement>(StatementList{})));
-
- auto* stmt = create<SwitchStatement>(ident, body);
- EXPECT_TRUE(stmt->IsValid());
+TEST_F(SwitchStatementTest, Assert_Null_Condition) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ CaseStatementList cases;
+ cases.push_back(
+ b.create<CaseStatement>(CaseSelectorList{b.Literal(1)},
+ b.create<BlockStatement>(StatementList{})));
+ b.create<SwitchStatement>(nullptr, cases);
+ },
+ "internal compiler error");
}
-TEST_F(SwitchStatementTest, IsValid_Null_Condition) {
- CaseSelectorList lit;
- lit.push_back(create<SintLiteral>(ty.i32(), 2));
-
- CaseStatementList body;
- body.push_back(
- create<CaseStatement>(lit, create<BlockStatement>(StatementList{})));
-
- auto* stmt = create<SwitchStatement>(nullptr, body);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(SwitchStatementTest, IsValid_Invalid_Condition) {
- CaseSelectorList lit;
- lit.push_back(create<SintLiteral>(ty.i32(), 2));
-
- auto* ident = Expr("");
- CaseStatementList body;
- body.push_back(
- create<CaseStatement>(lit, create<BlockStatement>(StatementList{})));
-
- auto* stmt = create<SwitchStatement>(ident, body);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(SwitchStatementTest, IsValid_Null_BodyStatement) {
- CaseSelectorList lit;
- lit.push_back(create<SintLiteral>(ty.i32(), 2));
-
- auto* ident = Expr("ident");
- CaseStatementList body;
- body.push_back(
- create<CaseStatement>(lit, create<BlockStatement>(StatementList{})));
- body.push_back(nullptr);
-
- auto* stmt = create<SwitchStatement>(ident, body);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(SwitchStatementTest, IsValid_Invalid_BodyStatement) {
- auto* ident = Expr("ident");
-
- auto* case_body = create<BlockStatement>(StatementList{
- nullptr,
- });
- CaseStatementList body;
- body.push_back(create<CaseStatement>(CaseSelectorList{}, case_body));
-
- auto* stmt = create<SwitchStatement>(ident, body);
- EXPECT_FALSE(stmt->IsValid());
+TEST_F(SwitchStatementTest, Assert_Null_CaseStatement) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<SwitchStatement>(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 c4f42ae..edf78fa 100644
--- a/src/ast/type_constructor_expression.cc
+++ b/src/ast/type_constructor_expression.cc
@@ -24,7 +24,12 @@
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 @@
return ctx->dst->create<TypeConstructorExpression>(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 30c5bbe..9381665 100644
--- a/src/ast/type_constructor_expression.h
+++ b/src/ast/type_constructor_expression.h
@@ -48,9 +48,6 @@
/// @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 d392294..b6c0e28 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 @@
EXPECT_TRUE(t->Is<TypeConstructorExpression>());
}
-TEST_F(TypeConstructorExpressionTest, IsValid) {
- ExpressionList expr;
- expr.push_back(Expr("expr"));
-
- auto* t = create<TypeConstructorExpression>(ty.f32(), expr);
- EXPECT_TRUE(t->IsValid());
+TEST_F(TypeConstructorExpressionTest, Assert_NullType) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<TypeConstructorExpression>(nullptr, ExpressionList{b.Expr(1)});
+ },
+ "internal compiler error");
}
-TEST_F(TypeConstructorExpressionTest, IsValid_EmptyValue) {
- ExpressionList expr;
-
- auto* t = create<TypeConstructorExpression>(ty.f32(), expr);
- EXPECT_TRUE(t->IsValid());
-}
-
-TEST_F(TypeConstructorExpressionTest, IsValid_NullType) {
- ExpressionList expr;
- expr.push_back(Expr("expr"));
-
- auto* t = create<TypeConstructorExpression>(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<TypeConstructorExpression>(ty.f32(), expr);
- EXPECT_FALSE(t->IsValid());
-}
-
-TEST_F(TypeConstructorExpressionTest, IsValid_InvalidValue) {
- ExpressionList expr;
- expr.push_back(Expr(""));
-
- auto* t = create<TypeConstructorExpression>(ty.f32(), expr);
- EXPECT_FALSE(t->IsValid());
+TEST_F(TypeConstructorExpressionTest, Assert_NullValue) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<TypeConstructorExpression>(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 3e5305b..166d3f0 100644
--- a/src/ast/unary_op_expression.cc
+++ b/src/ast/unary_op_expression.cc
@@ -24,7 +24,9 @@
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 @@
return ctx->dst->create<UnaryOpExpression>(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 60c97f0..91cd8ee 100644
--- a/src/ast/unary_op_expression.h
+++ b/src/ast/unary_op_expression.h
@@ -44,9 +44,6 @@
/// @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 8ac6082..2f1242a 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 @@
EXPECT_TRUE(u->Is<UnaryOpExpression>());
}
-TEST_F(UnaryOpExpressionTest, IsValid) {
- auto* ident = Expr("ident");
- auto* u = create<UnaryOpExpression>(UnaryOp::kNot, ident);
- EXPECT_TRUE(u->IsValid());
-}
-
-TEST_F(UnaryOpExpressionTest, IsValid_NullExpression) {
- auto* u = create<UnaryOpExpression>(UnaryOp::kNot, nullptr);
- EXPECT_FALSE(u->IsValid());
-}
-
-TEST_F(UnaryOpExpressionTest, IsValid_InvalidExpression) {
- auto* ident = Expr("");
- auto* u = create<UnaryOpExpression>(UnaryOp::kNot, ident);
- EXPECT_FALSE(u->IsValid());
+TEST_F(UnaryOpExpressionTest, Assert_NullExpression) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<UnaryOpExpression>(UnaryOp::kNot, nullptr);
+ },
+ "internal compiler error");
}
TEST_F(UnaryOpExpressionTest, ToStr) {
diff --git a/src/ast/variable.cc b/src/ast/variable.cc
index 0af22c0..9606b33 100644
--- a/src/ast/variable.cc
+++ b/src/ast/variable.cc
@@ -36,7 +36,10 @@
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 @@
}
uint32_t Variable::constant_id() const {
- assert(HasConstantIdDecoration());
+ TINT_ASSERT(HasConstantIdDecoration());
for (auto* deco : decorations_) {
if (auto* cid = deco->As<ConstantIdDecoration>()) {
return cid->value();
@@ -98,19 +101,6 @@
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 e5bcb0a..3e44dcf 100644
--- a/src/ast/variable.h
+++ b/src/ast/variable.h
@@ -137,9 +137,6 @@
/// @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 61d6121..9df4007 100644
--- a/src/ast/variable_decl_statement.cc
+++ b/src/ast/variable_decl_statement.cc
@@ -23,7 +23,9 @@
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 @@
return ctx->dst->create<VariableDeclStatement>(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 10de4a9..698d19a 100644
--- a/src/ast/variable_decl_statement.h
+++ b/src/ast/variable_decl_statement.h
@@ -42,9 +42,6 @@
/// @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 d3ebbb6..3447ca2 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 @@
EXPECT_TRUE(stmt->Is<VariableDeclStatement>());
}
-TEST_F(VariableDeclStatementTest, IsValid) {
- auto* var = Var("a", ty.f32(), StorageClass::kNone);
- auto* stmt = create<VariableDeclStatement>(var);
- EXPECT_TRUE(stmt->IsValid());
-}
-
-TEST_F(VariableDeclStatementTest, IsValid_InvalidVariable) {
- auto* var = Var("", ty.f32(), StorageClass::kNone);
- auto* stmt = create<VariableDeclStatement>(var);
- EXPECT_FALSE(stmt->IsValid());
-}
-
-TEST_F(VariableDeclStatementTest, IsValid_NullVariable) {
- auto* stmt = create<VariableDeclStatement>(nullptr);
- EXPECT_FALSE(stmt->IsValid());
+TEST_F(VariableDeclStatementTest, Assert_NullVariable) {
+ EXPECT_FATAL_FAILURE(
+ {
+ ProgramBuilder b;
+ b.create<VariableDeclStatement>(nullptr);
+ },
+ "internal compiler error");
}
TEST_F(VariableDeclStatementTest, ToStr) {
diff --git a/src/ast/variable_test.cc b/src/ast/variable_test.cc
index 6176024..5139080 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 @@
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 529a18b..372da30 100644
--- a/src/clone_context_test.cc
+++ b/src/clone_context_test.cc
@@ -37,7 +37,6 @@
return out;
}
- bool IsValid() const override { return true; }
void to_str(const semantic::Info&, std::ostream&, size_t) const override {}
};
@@ -55,7 +54,6 @@
return ctx->dst->create<NotANode>();
}
- 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 37e78bf..c65a044 100644
--- a/src/program_builder.cc
+++ b/src/program_builder.cc
@@ -60,7 +60,7 @@
}
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 daa2a70..700923c 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 @@
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<ast::ReturnStatement>(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 01e1a92..a5bb138 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -684,9 +684,6 @@
DefInfo::~DefInfo() = default;
-bool StatementBuilder::IsValid() const {
- return true;
-}
ast::Node* StatementBuilder::Clone(CloneContext*) const {
return nullptr;
}
@@ -4117,6 +4114,9 @@
for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
params.emplace_back(MakeOperand(inst, iarg).expr);
}
+ if (failed()) {
+ return false;
+ }
auto* call_expr =
create<ast::CallExpression>(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 086a02e..650d44b 100644
--- a/src/reader/spirv/function.h
+++ b/src/reader/spirv/function.h
@@ -368,7 +368,6 @@
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 0366523..49c5796 100644
--- a/src/resolver/validation_test.cc
+++ b/src/resolver/validation_test.cc
@@ -50,7 +50,6 @@
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 @@
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 8752e01..4a066fc 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -2715,8 +2715,10 @@
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();