[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);
|
||||
set_referenced_from_function_if_needed(var, true);
|
||||
|
||||
// If identifier is part of a loop continuing block, make sure it doesn't
|
||||
// refer to a variable that is bypassed by a continue statement in the
|
||||
// loop's body block.
|
||||
if (auto* continuing_block =
|
||||
current_block_->FindFirstParent(BlockInfo::Type::kLoopContinuing)) {
|
||||
auto* loop_block =
|
||||
continuing_block->FindFirstParent(BlockInfo::Type::kLoop);
|
||||
if (loop_block->first_continue != size_t(~0)) {
|
||||
auto& decls = loop_block->decls;
|
||||
// If our identifier is in loop_block->decls, make sure its index is
|
||||
// less than first_continue
|
||||
auto iter =
|
||||
std::find_if(decls.begin(), decls.end(),
|
||||
[&symbol](auto* v) { return v->symbol() == symbol; });
|
||||
if (iter != decls.end()) {
|
||||
auto var_decl_index =
|
||||
static_cast<size_t>(std::distance(decls.begin(), iter));
|
||||
if (var_decl_index >= loop_block->first_continue) {
|
||||
diagnostics_.add_error(
|
||||
"continue statement bypasses declaration of '" +
|
||||
builder_->Symbols().NameFor(symbol) +
|
||||
"' in continuing block",
|
||||
expr->source());
|
||||
return false;
|
||||
if (current_block_) {
|
||||
// If identifier is part of a loop continuing block, make sure it doesn't
|
||||
// refer to a variable that is bypassed by a continue statement in the
|
||||
// loop's body block.
|
||||
if (auto* continuing_block = current_block_->FindFirstParent(
|
||||
BlockInfo::Type::kLoopContinuing)) {
|
||||
auto* loop_block =
|
||||
continuing_block->FindFirstParent(BlockInfo::Type::kLoop);
|
||||
if (loop_block->first_continue != size_t(~0)) {
|
||||
auto& decls = loop_block->decls;
|
||||
// If our identifier is in loop_block->decls, make sure its index is
|
||||
// less than first_continue
|
||||
auto iter = std::find_if(
|
||||
decls.begin(), decls.end(),
|
||||
[&symbol](auto* v) { return v->symbol() == symbol; });
|
||||
if (iter != decls.end()) {
|
||||
auto var_decl_index =
|
||||
static_cast<size_t>(std::distance(decls.begin(), iter));
|
||||
if (var_decl_index >= loop_block->first_continue) {
|
||||
diagnostics_.add_error(
|
||||
"continue statement bypasses declaration of '" +
|
||||
builder_->Symbols().NameFor(symbol) +
|
||||
"' in continuing block",
|
||||
expr->source());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue