[resolver] Fix nullptr dereference when validating continuing block
ast::IdentifierExpression nodes can appear outside of functions (e.g. as initializers for module-scope variables), so we cannot assume that current_block_ is not nullptr. We already have several tests that do this, but for some reason the nullptr dereference does not cause problems on our presubmits. Change-Id: I612f3eb0d5711a0b1d0bb71663be7cca388b2b3c Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/45580 Auto-Submit: James Price <jrprice@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
91da97d6c3
commit
a07d21acc5
|
@ -832,30 +832,32 @@ bool Resolver::Identifier(ast::IdentifierExpression* expr) {
|
||||||
var->users.push_back(expr);
|
var->users.push_back(expr);
|
||||||
set_referenced_from_function_if_needed(var, true);
|
set_referenced_from_function_if_needed(var, true);
|
||||||
|
|
||||||
// If identifier is part of a loop continuing block, make sure it doesn't
|
if (current_block_) {
|
||||||
// refer to a variable that is bypassed by a continue statement in the
|
// If identifier is part of a loop continuing block, make sure it doesn't
|
||||||
// loop's body block.
|
// refer to a variable that is bypassed by a continue statement in the
|
||||||
if (auto* continuing_block =
|
// loop's body block.
|
||||||
current_block_->FindFirstParent(BlockInfo::Type::kLoopContinuing)) {
|
if (auto* continuing_block = current_block_->FindFirstParent(
|
||||||
auto* loop_block =
|
BlockInfo::Type::kLoopContinuing)) {
|
||||||
continuing_block->FindFirstParent(BlockInfo::Type::kLoop);
|
auto* loop_block =
|
||||||
if (loop_block->first_continue != size_t(~0)) {
|
continuing_block->FindFirstParent(BlockInfo::Type::kLoop);
|
||||||
auto& decls = loop_block->decls;
|
if (loop_block->first_continue != size_t(~0)) {
|
||||||
// If our identifier is in loop_block->decls, make sure its index is
|
auto& decls = loop_block->decls;
|
||||||
// less than first_continue
|
// If our identifier is in loop_block->decls, make sure its index is
|
||||||
auto iter =
|
// less than first_continue
|
||||||
std::find_if(decls.begin(), decls.end(),
|
auto iter = std::find_if(
|
||||||
[&symbol](auto* v) { return v->symbol() == symbol; });
|
decls.begin(), decls.end(),
|
||||||
if (iter != decls.end()) {
|
[&symbol](auto* v) { return v->symbol() == symbol; });
|
||||||
auto var_decl_index =
|
if (iter != decls.end()) {
|
||||||
static_cast<size_t>(std::distance(decls.begin(), iter));
|
auto var_decl_index =
|
||||||
if (var_decl_index >= loop_block->first_continue) {
|
static_cast<size_t>(std::distance(decls.begin(), iter));
|
||||||
diagnostics_.add_error(
|
if (var_decl_index >= loop_block->first_continue) {
|
||||||
"continue statement bypasses declaration of '" +
|
diagnostics_.add_error(
|
||||||
builder_->Symbols().NameFor(symbol) +
|
"continue statement bypasses declaration of '" +
|
||||||
"' in continuing block",
|
builder_->Symbols().NameFor(symbol) +
|
||||||
expr->source());
|
"' in continuing block",
|
||||||
return false;
|
expr->source());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue