Replace all uses of assert() with TINT_ICE macros

Use TINT_ICE() where we have diagnostics, TINT_ASSERT() where we do not.

Change-Id: Ic6e842a7afdd957654c3461e5d03ecec7332e6f9
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/46444
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
Ben Clayton 2021-03-31 20:43:26 +00:00 committed by Commit Bot service account
parent dba65b7a34
commit 90f43cf87f
23 changed files with 118 additions and 84 deletions

View File

@ -55,7 +55,10 @@ Module* Module::Clone(CloneContext* ctx) const {
void Module::Copy(CloneContext* ctx, const Module* src) { void Module::Copy(CloneContext* ctx, const Module* src) {
for (auto* decl : ctx->Clone(src->global_declarations_)) { for (auto* decl : ctx->Clone(src->global_declarations_)) {
assert(decl); if (!decl) {
TINT_ICE(ctx->dst->Diagnostics()) << "src global declaration was nullptr";
continue;
}
if (auto* ty = decl->As<type::Type>()) { if (auto* ty = decl->As<type::Type>()) {
AddConstructedType(ty); AddConstructedType(ty);
} else if (auto* func = decl->As<Function>()) { } else if (auto* func = decl->As<Function>()) {

View File

@ -44,7 +44,7 @@ namespace {
void AppendResourceBindings(std::vector<ResourceBinding>* dest, void AppendResourceBindings(std::vector<ResourceBinding>* dest,
const std::vector<ResourceBinding>& orig) { const std::vector<ResourceBinding>& orig) {
assert(dest); TINT_ASSERT(dest);
if (!dest) { if (!dest) {
return; return;
} }

View File

@ -1386,7 +1386,11 @@ semantic::Intrinsic* Impl::Overload::Match(ProgramBuilder& builder,
// This stage also populates the open_types and open_numbers. // This stage also populates the open_types and open_numbers.
auto count = std::min(parameters.size(), args.size()); auto count = std::min(parameters.size(), args.size());
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
assert(args[i]); if (!args[i]) {
TINT_ICE(diagnostics) << "args[" << i << "] is nullptr";
return nullptr;
}
auto* arg_ty = args[i]; auto* arg_ty = args[i];
if (auto* ptr = arg_ty->As<type::Pointer>()) { if (auto* ptr = arg_ty->As<type::Pointer>()) {
if (!parameters[i].matcher->ExpectsPointer()) { if (!parameters[i].matcher->ExpectsPointer()) {
@ -1447,7 +1451,10 @@ semantic::Intrinsic* Impl::Overload::Match(ProgramBuilder& builder,
Builder::BuildState builder_state{builder.Types(), matcher_state.open_types, Builder::BuildState builder_state{builder.Types(), matcher_state.open_types,
matcher_state.open_numbers}; matcher_state.open_numbers};
auto* ret = return_type->Build(builder_state); auto* ret = return_type->Build(builder_state);
assert(ret); // Build() must return a type if (!ret) {
TINT_ICE(diagnostics) << "Build() did not return a type";
return nullptr;
}
// Build the semantic parameters // Build the semantic parameters
semantic::ParameterList params; semantic::ParameterList params;

View File

@ -119,7 +119,7 @@ std::string Program::str(const ast::Node* node) const {
} }
void Program::AssertNotMoved() const { void Program::AssertNotMoved() const {
assert(!moved_); TINT_ASSERT(!moved_);
} }
} // namespace tint } // namespace tint

View File

@ -17,6 +17,7 @@
#include "src/ast/assignment_statement.h" #include "src/ast/assignment_statement.h"
#include "src/ast/call_statement.h" #include "src/ast/call_statement.h"
#include "src/ast/variable_decl_statement.h" #include "src/ast/variable_decl_statement.h"
#include "src/debug.h"
#include "src/demangler.h" #include "src/demangler.h"
#include "src/semantic/expression.h" #include "src/semantic/expression.h"
@ -74,7 +75,10 @@ void ProgramBuilder::MarkAsMoved() {
} }
void ProgramBuilder::AssertNotMoved() const { void ProgramBuilder::AssertNotMoved() const {
assert(!moved_); if (moved_) {
TINT_ICE(const_cast<ProgramBuilder*>(this)->Diagnostics())
<< "Attempting to use ProgramBuilder after it has been moved";
}
} }
type::Type* ProgramBuilder::TypeOf(ast::Expression* expr) const { type::Type* ProgramBuilder::TypeOf(ast::Expression* expr) const {

View File

@ -734,7 +734,7 @@ FunctionEmitter::StatementBlock::StatementBlock(StatementBlock&& other) =
FunctionEmitter::StatementBlock::~StatementBlock() = default; FunctionEmitter::StatementBlock::~StatementBlock() = default;
void FunctionEmitter::StatementBlock::Finalize(ProgramBuilder* pb) { void FunctionEmitter::StatementBlock::Finalize(ProgramBuilder* pb) {
assert(!finalized_ /* Finalize() must only be called once */); TINT_ASSERT(!finalized_ /* Finalize() must only be called once */);
for (size_t i = 0; i < statements_.size(); i++) { for (size_t i = 0; i < statements_.size(); i++) {
if (auto* sb = statements_[i]->As<StatementBuilder>()) { if (auto* sb = statements_[i]->As<StatementBuilder>()) {
@ -750,7 +750,7 @@ void FunctionEmitter::StatementBlock::Finalize(ProgramBuilder* pb) {
} }
void FunctionEmitter::StatementBlock::Add(ast::Statement* statement) { void FunctionEmitter::StatementBlock::Add(ast::Statement* statement) {
assert(!finalized_ /* Add() must not be called after Finalize() */); TINT_ASSERT(!finalized_ /* Add() must not be called after Finalize() */);
statements_.emplace_back(statement); statements_.emplace_back(statement);
} }
@ -762,8 +762,8 @@ void FunctionEmitter::PushNewStatementBlock(const Construct* construct,
void FunctionEmitter::PushGuard(const std::string& guard_name, void FunctionEmitter::PushGuard(const std::string& guard_name,
uint32_t end_id) { uint32_t end_id) {
assert(!statements_stack_.empty()); TINT_ASSERT(!statements_stack_.empty());
assert(!guard_name.empty()); TINT_ASSERT(!guard_name.empty());
// Guard control flow by the guard variable. Introduce a new // Guard control flow by the guard variable. Introduce a new
// if-selection with a then-clause ending at the same block // if-selection with a then-clause ending at the same block
// as the statement block at the top of the stack. // as the statement block at the top of the stack.
@ -780,7 +780,7 @@ void FunctionEmitter::PushGuard(const std::string& guard_name,
} }
void FunctionEmitter::PushTrueGuard(uint32_t end_id) { void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
assert(!statements_stack_.empty()); TINT_ASSERT(!statements_stack_.empty());
const auto& top = statements_stack_.back(); const auto& top = statements_stack_.back();
auto* cond = MakeTrue(Source{}); auto* cond = MakeTrue(Source{});
@ -793,14 +793,14 @@ void FunctionEmitter::PushTrueGuard(uint32_t end_id) {
} }
const ast::StatementList FunctionEmitter::ast_body() { const ast::StatementList FunctionEmitter::ast_body() {
assert(!statements_stack_.empty()); TINT_ASSERT(!statements_stack_.empty());
auto& entry = statements_stack_[0]; auto& entry = statements_stack_[0];
entry.Finalize(&builder_); entry.Finalize(&builder_);
return entry.GetStatements(); return entry.GetStatements();
} }
ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) { ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
assert(!statements_stack_.empty()); TINT_ASSERT(!statements_stack_.empty());
if (statement != nullptr) { if (statement != nullptr) {
statements_stack_.back().Add(statement); statements_stack_.back().Add(statement);
} }
@ -808,9 +808,9 @@ ast::Statement* FunctionEmitter::AddStatement(ast::Statement* statement) {
} }
ast::Statement* FunctionEmitter::LastStatement() { ast::Statement* FunctionEmitter::LastStatement() {
assert(!statements_stack_.empty()); TINT_ASSERT(!statements_stack_.empty());
auto& statement_list = statements_stack_.back().GetStatements(); auto& statement_list = statements_stack_.back().GetStatements();
assert(!statement_list.empty()); TINT_ASSERT(!statement_list.empty());
return statement_list.back(); return statement_list.back();
} }
@ -1221,7 +1221,7 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
// block. Also mark the the most recent continue target for which we // block. Also mark the the most recent continue target for which we
// haven't reached the backedge block. // haven't reached the backedge block.
assert(block_order_.size() > 0); TINT_ASSERT(block_order_.size() > 0);
constructs_.clear(); constructs_.clear();
const auto entry_id = block_order_[0]; const auto entry_id = block_order_[0];
@ -1242,8 +1242,8 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
// A loop construct is added right after its associated continue construct. // A loop construct is added right after its associated continue construct.
// In that case, adjust the parent up. // In that case, adjust the parent up.
if (k == Construct::kLoop) { if (k == Construct::kLoop) {
assert(parent); TINT_ASSERT(parent);
assert(parent->kind == Construct::kContinue); TINT_ASSERT(parent->kind == Construct::kContinue);
scope_end_pos = parent->end_pos; scope_end_pos = parent->end_pos;
parent = parent->parent; parent = parent->parent;
} }
@ -1262,9 +1262,9 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
for (uint32_t i = 0; i < block_order_.size(); ++i) { for (uint32_t i = 0; i < block_order_.size(); ++i) {
const auto block_id = block_order_[i]; const auto block_id = block_order_[i];
assert(block_id > 0); TINT_ASSERT(block_id > 0);
auto* block_info = GetBlockInfo(block_id); auto* block_info = GetBlockInfo(block_id);
assert(block_info); TINT_ASSERT(block_info);
if (enclosing.empty()) { if (enclosing.empty()) {
return Fail() << "internal error: too many merge blocks before block " return Fail() << "internal error: too many merge blocks before block "
@ -1321,7 +1321,7 @@ bool FunctionEmitter::LabelControlFlowConstructs() {
} }
} }
assert(top); TINT_ASSERT(top);
block_info->construct = top; block_info->construct = top;
} }
@ -1530,9 +1530,9 @@ bool FunctionEmitter::ClassifyCFGEdges() {
// NEC(S) is the parent of NEC(T). // NEC(S) is the parent of NEC(T).
for (const auto src : block_order_) { for (const auto src : block_order_) {
assert(src > 0); TINT_ASSERT(src > 0);
auto* src_info = GetBlockInfo(src); auto* src_info = GetBlockInfo(src);
assert(src_info); TINT_ASSERT(src_info);
const auto src_pos = src_info->pos; const auto src_pos = src_info->pos;
const auto& src_construct = *(src_info->construct); const auto& src_construct = *(src_info->construct);
@ -1570,7 +1570,7 @@ bool FunctionEmitter::ClassifyCFGEdges() {
for (const auto dest : successors) { for (const auto dest : successors) {
const auto* dest_info = GetBlockInfo(dest); const auto* dest_info = GetBlockInfo(dest);
// We've already checked terminators are valid. // We've already checked terminators are valid.
assert(dest_info); TINT_ASSERT(dest_info);
const auto dest_pos = dest_info->pos; const auto dest_pos = dest_info->pos;
// Insert the edge kind entry and keep a handle to update // Insert the edge kind entry and keep a handle to update
@ -1595,7 +1595,7 @@ bool FunctionEmitter::ClassifyCFGEdges() {
<< " (violates post-dominance rule)"; << " (violates post-dominance rule)";
} }
const auto* ct_info = GetBlockInfo(continue_construct->begin_id); const auto* ct_info = GetBlockInfo(continue_construct->begin_id);
assert(ct_info); TINT_ASSERT(ct_info);
if (ct_info->header_for_continue != dest) { if (ct_info->header_for_continue != dest) {
return Fail() return Fail()
<< "Invalid backedge (" << src << "->" << dest << "Invalid backedge (" << src << "->" << dest
@ -1874,7 +1874,7 @@ bool FunctionEmitter::FindIfSelectionInternalHeaders() {
// The first clause might be a then-clause or an else-clause. // The first clause might be a then-clause or an else-clause.
const auto second_head = std::max(true_head_pos, false_head_pos); const auto second_head = std::max(true_head_pos, false_head_pos);
const auto end_first_clause_pos = second_head - 1; const auto end_first_clause_pos = second_head - 1;
assert(end_first_clause_pos < block_order_.size()); TINT_ASSERT(end_first_clause_pos < block_order_.size());
const auto end_first_clause = block_order_[end_first_clause_pos]; const auto end_first_clause = block_order_[end_first_clause_pos];
uint32_t premerge_id = 0; uint32_t premerge_id = 0;
uint32_t if_break_id = 0; uint32_t if_break_id = 0;
@ -2072,15 +2072,15 @@ bool FunctionEmitter::EmitFunctionBodyStatements() {
// Upon entry, the statement stack has one entry representing the whole // Upon entry, the statement stack has one entry representing the whole
// function. // function.
assert(!constructs_.empty()); TINT_ASSERT(!constructs_.empty());
Construct* function_construct = constructs_[0].get(); Construct* function_construct = constructs_[0].get();
assert(function_construct != nullptr); TINT_ASSERT(function_construct != nullptr);
assert(function_construct->kind == Construct::kFunction); TINT_ASSERT(function_construct->kind == Construct::kFunction);
// Make the first entry valid by filling in the construct field, which // Make the first entry valid by filling in the construct field, which
// had not been computed at the time the entry was first created. // had not been computed at the time the entry was first created.
// TODO(dneto): refactor how the first construct is created vs. // TODO(dneto): refactor how the first construct is created vs.
// this statements stack entry is populated. // this statements stack entry is populated.
assert(statements_stack_.size() == 1); TINT_ASSERT(statements_stack_.size() == 1);
statements_stack_[0].SetConstruct(function_construct); statements_stack_[0].SetConstruct(function_construct);
for (auto block_id : block_order()) { for (auto block_id : block_order()) {
@ -2270,8 +2270,8 @@ bool FunctionEmitter::EmitBasicBlock(const BlockInfo& block_info) {
bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) { bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
// The block is the if-header block. So its construct is the if construct. // The block is the if-header block. So its construct is the if construct.
auto* construct = block_info.construct; auto* construct = block_info.construct;
assert(construct->kind == Construct::kIfSelection); TINT_ASSERT(construct->kind == Construct::kIfSelection);
assert(construct->begin_id == block_info.id); TINT_ASSERT(construct->begin_id == block_info.id);
const uint32_t true_head = block_info.true_head; const uint32_t true_head = block_info.true_head;
const uint32_t false_head = block_info.false_head; const uint32_t false_head = block_info.false_head;
@ -2396,8 +2396,8 @@ bool FunctionEmitter::EmitIfStart(const BlockInfo& block_info) {
bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) { bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
// The block is the if-header block. So its construct is the if construct. // The block is the if-header block. So its construct is the if construct.
auto* construct = block_info.construct; auto* construct = block_info.construct;
assert(construct->kind == Construct::kSwitchSelection); TINT_ASSERT(construct->kind == Construct::kSwitchSelection);
assert(construct->begin_id == block_info.id); TINT_ASSERT(construct->begin_id == block_info.id);
const auto* branch = block_info.basic_block->terminator(); const auto* branch = block_info.basic_block->terminator();
const auto selector_id = branch->GetSingleWordInOperand(0); const auto selector_id = branch->GetSingleWordInOperand(0);
@ -2443,7 +2443,7 @@ bool FunctionEmitter::EmitSwitchStart(const BlockInfo& block_info) {
clause_heads[w] = clause_heads[r]; clause_heads[w] = clause_heads[r];
} }
// We know it's not empty because it always has at least a default clause. // We know it's not empty because it always has at least a default clause.
assert(!clause_heads.empty()); TINT_ASSERT(!clause_heads.empty());
clause_heads.resize(w + 1); clause_heads.resize(w + 1);
} }
@ -2652,9 +2652,9 @@ ast::Statement* FunctionEmitter::MakeBranchDetailed(
// Unless forced, don't bother with a break at the end of a case/default // Unless forced, don't bother with a break at the end of a case/default
// clause. // clause.
const auto header = dest_info.header_for_merge; const auto header = dest_info.header_for_merge;
assert(header != 0); TINT_ASSERT(header != 0);
const auto* exiting_construct = GetBlockInfo(header)->construct; const auto* exiting_construct = GetBlockInfo(header)->construct;
assert(exiting_construct->kind == Construct::kSwitchSelection); TINT_ASSERT(exiting_construct->kind == Construct::kSwitchSelection);
const auto candidate_next_case_pos = src_info.pos + 1; const auto candidate_next_case_pos = src_info.pos + 1;
// Leaving the last block from the last case? // Leaving the last block from the last case?
if (candidate_next_case_pos == dest_info.pos) { if (candidate_next_case_pos == dest_info.pos) {
@ -2798,7 +2798,7 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
// Emit declarations of hoisted variables, in index order. // Emit declarations of hoisted variables, in index order.
for (auto id : sorted_by_index(block_info.hoisted_ids)) { for (auto id : sorted_by_index(block_info.hoisted_ids)) {
const auto* def_inst = def_use_mgr_->GetDef(id); const auto* def_inst = def_use_mgr_->GetDef(id);
assert(def_inst); TINT_ASSERT(def_inst);
auto* ast_type = auto* ast_type =
RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id); RemapStorageClass(parser_impl_.ConvertType(def_inst->type_id()), id);
AddStatement(create<ast::VariableDeclStatement>( AddStatement(create<ast::VariableDeclStatement>(
@ -2811,9 +2811,9 @@ bool FunctionEmitter::EmitStatementsInBasicBlock(const BlockInfo& block_info,
// Emit declarations of phi state variables, in index order. // Emit declarations of phi state variables, in index order.
for (auto id : sorted_by_index(block_info.phis_needing_state_vars)) { for (auto id : sorted_by_index(block_info.phis_needing_state_vars)) {
const auto* def_inst = def_use_mgr_->GetDef(id); const auto* def_inst = def_use_mgr_->GetDef(id);
assert(def_inst); TINT_ASSERT(def_inst);
const auto phi_var_name = GetDefInfo(id)->phi_var; const auto phi_var_name = GetDefInfo(id)->phi_var;
assert(!phi_var_name.empty()); TINT_ASSERT(!phi_var_name.empty());
auto* var = create<ast::Variable>( auto* var = create<ast::Variable>(
Source{}, // source Source{}, // source
builder_.Symbols().Register(phi_var_name), // symbol builder_.Symbols().Register(phi_var_name), // symbol
@ -3066,7 +3066,7 @@ bool FunctionEmitter::EmitStatement(const spvtools::opt::Instruction& inst) {
} }
auto expr = MakeExpression(ptr_id); auto expr = MakeExpression(ptr_id);
// The load result type is the pointee type of its operand. // The load result type is the pointee type of its operand.
assert(expr.type->Is<type::Pointer>()); TINT_ASSERT(expr.type->Is<type::Pointer>());
expr.type = expr.type->As<type::Pointer>()->type(); expr.type = expr.type->As<type::Pointer>()->type();
return EmitConstDefOrWriteToHoistedVar(inst, expr); return EmitConstDefOrWriteToHoistedVar(inst, expr);
} }
@ -3550,8 +3550,8 @@ TypedExpression FunctionEmitter::MakeAccessChain(
const auto pointer_type_id = const auto pointer_type_id =
type_mgr_->FindPointerToType(pointee_type_id, storage_class); type_mgr_->FindPointerToType(pointee_type_id, storage_class);
auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id); auto* ast_pointer_type = parser_impl_.ConvertType(pointer_type_id);
assert(ast_pointer_type); TINT_ASSERT(ast_pointer_type);
assert(ast_pointer_type->Is<type::Pointer>()); TINT_ASSERT(ast_pointer_type->Is<type::Pointer>());
current_expr = TypedExpression{ast_pointer_type, next_expr}; current_expr = TypedExpression{ast_pointer_type, next_expr};
} }
return current_expr; return current_expr;
@ -3746,7 +3746,7 @@ TypedExpression FunctionEmitter::MakeVectorShuffle(
source, MakeExpression(vec0_id).expr, Swizzle(index))); source, MakeExpression(vec0_id).expr, Swizzle(index)));
} else if (index < vec0_len + vec1_len) { } else if (index < vec0_len + vec1_len) {
const auto sub_index = index - vec0_len; const auto sub_index = index - vec0_len;
assert(sub_index < kMaxVectorLen); TINT_ASSERT(sub_index < kMaxVectorLen);
values.emplace_back(create<ast::MemberAccessorExpression>( values.emplace_back(create<ast::MemberAccessorExpression>(
source, MakeExpression(vec1_id).expr, Swizzle(sub_index))); source, MakeExpression(vec1_id).expr, Swizzle(sub_index)));
} else if (index == 0xFFFFFFFF) { } else if (index == 0xFFFFFFFF) {
@ -4045,7 +4045,7 @@ const Construct* FunctionEmitter::GetEnclosingScope(uint32_t first_pos,
uint32_t last_pos) const { uint32_t last_pos) const {
const auto* enclosing_construct = const auto* enclosing_construct =
GetBlockInfo(block_order_[first_pos])->construct; GetBlockInfo(block_order_[first_pos])->construct;
assert(enclosing_construct != nullptr); TINT_ASSERT(enclosing_construct != nullptr);
// Constructs are strictly nesting, so follow parent pointers // Constructs are strictly nesting, so follow parent pointers
while (enclosing_construct && while (enclosing_construct &&
!enclosing_construct->ScopeContainsPos(last_pos)) { !enclosing_construct->ScopeContainsPos(last_pos)) {
@ -4057,7 +4057,7 @@ const Construct* FunctionEmitter::GetEnclosingScope(uint32_t first_pos,
sibling_loop ? sibling_loop : enclosing_construct->parent; sibling_loop ? sibling_loop : enclosing_construct->parent;
} }
// At worst, we go all the way out to the function construct. // At worst, we go all the way out to the function construct.
assert(enclosing_construct != nullptr); TINT_ASSERT(enclosing_construct != nullptr);
return enclosing_construct; return enclosing_construct;
} }

View File

@ -998,7 +998,7 @@ class FunctionEmitter {
/// @return the built StatementBuilder /// @return the built StatementBuilder
template <typename T, typename... ARGS> template <typename T, typename... ARGS>
T* AddStatementBuilder(ARGS&&... args) { T* AddStatementBuilder(ARGS&&... args) {
assert(!statements_stack_.empty()); TINT_ASSERT(!statements_stack_.empty());
return statements_stack_.back().AddStatementBuilder<T>( return statements_stack_.back().AddStatementBuilder<T>(
std::forward<ARGS>(args)...); std::forward<ARGS>(args)...);
} }

View File

@ -233,7 +233,6 @@ Token ParserImpl::peek() {
void ParserImpl::register_constructed(const std::string& name, void ParserImpl::register_constructed(const std::string& name,
type::Type* type) { type::Type* type) {
assert(type);
registered_constructs_[name] = type; registered_constructs_[name] = type;
} }
@ -3156,7 +3155,9 @@ T ParserImpl::sync(Token::Type tok, F&& body) {
auto result = body(); auto result = body();
--sync_depth_; --sync_depth_;
assert(sync_tokens_.back() == tok); if (sync_tokens_.back() != tok) {
TINT_ICE(builder_.Diagnostics()) << "sync_tokens is out of sync";
}
sync_tokens_.pop_back(); sync_tokens_.pop_back();
if (result.errored) { if (result.errored) {

View File

@ -109,7 +109,7 @@ class ParserImpl {
/// return type will always be a pointer to a non-pointer type. #errored /// return type will always be a pointer to a non-pointer type. #errored
/// must be false to call. /// must be false to call.
inline typename detail::OperatorArrow<T>::type operator->() { inline typename detail::OperatorArrow<T>::type operator->() {
assert(!errored); TINT_ASSERT(!errored);
return detail::OperatorArrow<T>::ptr(value); return detail::OperatorArrow<T>::ptr(value);
} }
@ -180,7 +180,7 @@ class ParserImpl {
/// return type will always be a pointer to a non-pointer type. #errored /// return type will always be a pointer to a non-pointer type. #errored
/// must be false to call. /// must be false to call.
inline typename detail::OperatorArrow<T>::type operator->() { inline typename detail::OperatorArrow<T>::type operator->() {
assert(!errored); TINT_ASSERT(!errored);
return detail::OperatorArrow<T>::ptr(value); return detail::OperatorArrow<T>::ptr(value);
} }

View File

@ -1329,7 +1329,10 @@ type::Type* Resolver::TypeOf(ast::Expression* expr) {
} }
void Resolver::SetType(ast::Expression* expr, type::Type* type) { void Resolver::SetType(ast::Expression* expr, type::Type* type) {
assert(expr_info_.count(expr) == 0); if (expr_info_.count(expr)) {
TINT_ICE(builder_->Diagnostics())
<< "SetType() called twice for the same expression";
}
expr_info_.emplace(expr, ExpressionInfo{type, current_statement_}); expr_info_.emplace(expr, ExpressionInfo{type, current_statement_});
} }

View File

@ -15,10 +15,9 @@
#ifndef SRC_SEMANTIC_INFO_H_ #ifndef SRC_SEMANTIC_INFO_H_
#define SRC_SEMANTIC_INFO_H_ #define SRC_SEMANTIC_INFO_H_
#include <assert.h>
#include <unordered_map> #include <unordered_map>
#include "src/debug.h"
#include "src/semantic/node.h" #include "src/semantic/node.h"
#include "src/semantic/type_mappings.h" #include "src/semantic/type_mappings.h"
@ -63,7 +62,7 @@ class Info {
void Add(const AST_OR_TYPE* node, void Add(const AST_OR_TYPE* node,
const SemanticNodeTypeFor<AST_OR_TYPE>* sem_node) { const SemanticNodeTypeFor<AST_OR_TYPE>* sem_node) {
// Check there's no semantic info already existing for the node // Check there's no semantic info already existing for the node
assert(Get(node) == nullptr); TINT_ASSERT(Get(node) == nullptr);
map.emplace(node, sem_node); map.emplace(node, sem_node);
} }

View File

@ -23,8 +23,8 @@ namespace type {
AccessControl::AccessControl(ast::AccessControl access, Type* subtype) AccessControl::AccessControl(ast::AccessControl access, Type* subtype)
: access_(access), subtype_(subtype) { : access_(access), subtype_(subtype) {
assert(subtype_); TINT_ASSERT(subtype_);
assert(!subtype_->Is<AccessControl>()); TINT_ASSERT(!subtype_->Is<AccessControl>());
} }
AccessControl::AccessControl(AccessControl&&) = default; AccessControl::AccessControl(AccessControl&&) = default;

View File

@ -23,7 +23,7 @@ namespace type {
Alias::Alias(const Symbol& sym, Type* subtype) Alias::Alias(const Symbol& sym, Type* subtype)
: symbol_(sym), subtype_(subtype) { : symbol_(sym), subtype_(subtype) {
assert(subtype_); TINT_ASSERT(subtype_);
} }
Alias::Alias(Alias&&) = default; Alias::Alias(Alias&&) = default;

View File

@ -31,7 +31,7 @@ Array::Array(Array&&) = default;
Array::~Array() = default; Array::~Array() = default;
std::string Array::type_name() const { std::string Array::type_name() const {
assert(subtype_); TINT_ASSERT(subtype_);
std::string type_name = "__array" + subtype_->type_name(); std::string type_name = "__array" + subtype_->type_name();
if (!IsRuntimeArray()) { if (!IsRuntimeArray()) {

View File

@ -22,19 +22,15 @@ namespace tint {
namespace type { namespace type {
namespace { namespace {
#ifndef NDEBUG
bool IsValidDepthDimension(TextureDimension dim) { bool IsValidDepthDimension(TextureDimension dim) {
return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray || return dim == TextureDimension::k2d || dim == TextureDimension::k2dArray ||
dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray; dim == TextureDimension::kCube || dim == TextureDimension::kCubeArray;
} }
#endif // NDEBUG
} // namespace } // namespace
DepthTexture::DepthTexture(TextureDimension dim) : Base(dim) { DepthTexture::DepthTexture(TextureDimension dim) : Base(dim) {
assert(IsValidDepthDimension(dim)); TINT_ASSERT(IsValidDepthDimension(dim));
} }
DepthTexture::DepthTexture(DepthTexture&&) = default; DepthTexture::DepthTexture(DepthTexture&&) = default;

View File

@ -23,10 +23,10 @@ namespace type {
Matrix::Matrix(Type* subtype, uint32_t rows, uint32_t columns) Matrix::Matrix(Type* subtype, uint32_t rows, uint32_t columns)
: subtype_(subtype), rows_(rows), columns_(columns) { : subtype_(subtype), rows_(rows), columns_(columns) {
assert(rows > 1); TINT_ASSERT(rows > 1);
assert(rows < 5); TINT_ASSERT(rows < 5);
assert(columns > 1); TINT_ASSERT(columns > 1);
assert(columns < 5); TINT_ASSERT(columns < 5);
} }
Matrix::Matrix(Matrix&&) = default; Matrix::Matrix(Matrix&&) = default;

View File

@ -23,7 +23,7 @@ namespace type {
MultisampledTexture::MultisampledTexture(TextureDimension dim, Type* type) MultisampledTexture::MultisampledTexture(TextureDimension dim, Type* type)
: Base(dim), type_(type) { : Base(dim), type_(type) {
assert(type_); TINT_ASSERT(type_);
} }
MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default; MultisampledTexture::MultisampledTexture(MultisampledTexture&&) = default;

View File

@ -23,7 +23,7 @@ namespace type {
SampledTexture::SampledTexture(TextureDimension dim, Type* type) SampledTexture::SampledTexture(TextureDimension dim, Type* type)
: Base(dim), type_(type) { : Base(dim), type_(type) {
assert(type_); TINT_ASSERT(type_);
} }
SampledTexture::SampledTexture(SampledTexture&&) = default; SampledTexture::SampledTexture(SampledTexture&&) = default;

View File

@ -22,8 +22,8 @@ namespace tint {
namespace type { namespace type {
Vector::Vector(Type* subtype, uint32_t size) : subtype_(subtype), size_(size) { Vector::Vector(Type* subtype, uint32_t size) : subtype_(subtype), size_(size) {
assert(size_ > 1); TINT_ASSERT(size_ > 1);
assert(size_ < 5); TINT_ASSERT(size_ < 5);
} }
Vector::Vector(Vector&&) = default; Vector::Vector(Vector&&) = default;

View File

@ -776,7 +776,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
}; };
auto* texture = arg(Usage::kTexture); auto* texture = arg(Usage::kTexture);
assert(texture); if (!texture) {
TINT_ICE(diagnostics_) << "missing texture argument";
return false;
}
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>(); auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
@ -934,8 +937,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
pre << dims; pre << dims;
} else { } else {
static constexpr char xyzw[] = {'x', 'y', 'z', 'w'}; static constexpr char xyzw[] = {'x', 'y', 'z', 'w'};
assert(num_dimensions > 0); if (num_dimensions < 0 || num_dimensions > 4) {
assert(num_dimensions <= 4); TINT_ICE(diagnostics_) << "vector dimensions are " << num_dimensions;
return false;
}
for (int i = 0; i < num_dimensions; i++) { for (int i = 0; i < num_dimensions; i++) {
if (i > 0) { if (i > 0) {
pre << ", "; pre << ", ";
@ -999,7 +1004,10 @@ bool GeneratorImpl::EmitTextureCall(std::ostream& pre,
} }
auto* param_coords = arg(Usage::kCoords); auto* param_coords = arg(Usage::kCoords);
assert(param_coords); if (!param_coords) {
TINT_ICE(diagnostics_) << "missing coords argument";
return false;
}
auto emit_vector_appended_with_i32_zero = [&](tint::ast::Expression* vector) { auto emit_vector_appended_with_i32_zero = [&](tint::ast::Expression* vector) {
auto* i32 = builder_.create<type::I32>(); auto* i32 = builder_.create<type::I32>();

View File

@ -474,7 +474,10 @@ bool GeneratorImpl::EmitTextureCall(ast::CallExpression* expr,
}; };
auto* texture = arg(Usage::kTexture); auto* texture = arg(Usage::kTexture);
assert(texture); if (!texture) {
TINT_ICE(diagnostics_) << "missing texture arg";
return false;
}
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>(); auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();

View File

@ -1007,8 +1007,11 @@ bool Builder::GenerateMemberAccessor(ast::MemberAccessorExpression* expr,
} }
uint32_t Builder::GenerateAccessorExpression(ast::Expression* expr) { uint32_t Builder::GenerateAccessorExpression(ast::Expression* expr) {
assert(expr->Is<ast::ArrayAccessorExpression>() || if (!expr->IsAnyOf<ast::ArrayAccessorExpression,
expr->Is<ast::MemberAccessorExpression>()); ast::MemberAccessorExpression>()) {
TINT_ICE(builder_.Diagnostics()) << "expression is not an accessor";
return 0;
}
// Gather a list of all the member and array accessors that are in this chain. // Gather a list of all the member and array accessors that are in this chain.
// The list is built in reverse order as that's the order we need to access // The list is built in reverse order as that's the order we need to access
@ -2113,12 +2116,17 @@ bool Builder::GenerateTextureIntrinsic(ast::CallExpression* call,
// Generates the argument with the given usage, returning the operand ID // Generates the argument with the given usage, returning the operand ID
auto gen_arg = [&](Usage usage) { auto gen_arg = [&](Usage usage) {
auto* argument = arg(usage); auto* argument = arg(usage);
assert(argument); if (!argument) {
TINT_ICE(builder_.Diagnostics())
<< "missing argument " << static_cast<int>(usage);
}
return gen(argument); return gen(argument);
}; };
auto* texture = arg(Usage::kTexture); auto* texture = arg(Usage::kTexture);
assert(texture); if (!texture) {
TINT_ICE(builder_.Diagnostics()) << "missing texture argument";
}
auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>(); auto* texture_type = TypeOf(texture)->UnwrapAll()->As<type::Texture>();
@ -3007,8 +3015,7 @@ bool Builder::GenerateTextureType(type::Texture* texture,
dim_literal = SpvDim1D; dim_literal = SpvDim1D;
if (texture->Is<type::SampledTexture>()) { if (texture->Is<type::SampledTexture>()) {
push_capability(SpvCapabilitySampled1D); push_capability(SpvCapabilitySampled1D);
} else { } else if (texture->Is<type::StorageTexture>()) {
assert(texture->Is<type::StorageTexture>());
push_capability(SpvCapabilityImage1D); push_capability(SpvCapabilityImage1D);
} }
} }

View File

@ -191,7 +191,10 @@ class Builder {
/// Pushes a variable to the current function /// Pushes a variable to the current function
/// @param operands the variable operands /// @param operands the variable operands
void push_function_var(const OperandList& operands) { void push_function_var(const OperandList& operands) {
assert(!functions_.empty()); if (functions_.empty()) {
TINT_ICE(builder_.Diagnostics())
<< "push_function_var() called without a function";
}
functions_.back().push_var(operands); functions_.back().push_var(operands);
} }