[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>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 43b28b4..00cf333 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -832,30 +832,32 @@
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;
+ }
}
}
}