Resolver: Validation for continuing blocks
Check they do not contain returns, discards
Check they do not directly contain continues, however a nested loop can have its own continue.
Bug: chromium:1229976
Change-Id: Ia3c4ac118ffdaa6cca6025366c19f9897718c930
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/58384
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: David Neto <dneto@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 8288a3f..ca5ea27 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -2062,11 +2062,18 @@
}
if (stmt->Is<ast::ContinueStatement>()) {
// Set if we've hit the first continue statement in our parent loop
- if (auto* loop_block =
- current_block_->FindFirstParent<sem::LoopBlockStatement>()) {
- if (loop_block->FirstContinue() == size_t(~0)) {
- const_cast<sem::LoopBlockStatement*>(loop_block)
- ->SetFirstContinue(loop_block->Decls().size());
+ if (auto* block =
+ current_block_->FindFirstParent<
+ sem::LoopBlockStatement, sem::LoopContinuingBlockStatement>()) {
+ if (auto* loop_block = block->As<sem::LoopBlockStatement>()) {
+ if (loop_block->FirstContinue() == size_t(~0)) {
+ const_cast<sem::LoopBlockStatement*>(loop_block)
+ ->SetFirstContinue(loop_block->Decls().size());
+ }
+ } else {
+ AddError("continuing blocks must not contain a continue statement",
+ stmt->source());
+ return false;
}
} else {
AddError("continue statement must be in a loop", stmt->source());
@@ -2076,6 +2083,17 @@
return true;
}
if (stmt->Is<ast::DiscardStatement>()) {
+ if (auto* continuing =
+ sem_statement
+ ->FindFirstParent<sem::LoopContinuingBlockStatement>()) {
+ AddError("continuing blocks must not contain a discard statement",
+ stmt->source());
+ if (continuing != sem_statement->Parent()) {
+ AddNote("see continuing block here",
+ continuing->Declaration()->source());
+ }
+ return false;
+ }
return true;
}
if (stmt->Is<ast::FallthroughStatement>()) {
@@ -4110,6 +4128,17 @@
return false;
}
+ auto* sem = builder_->Sem().Get(ret);
+ if (auto* continuing =
+ sem->FindFirstParent<sem::LoopContinuingBlockStatement>()) {
+ AddError("continuing blocks must not contain a return statement",
+ ret->source());
+ if (continuing != sem->Parent()) {
+ AddNote("see continuing block here", continuing->Declaration()->source());
+ }
+ return false;
+ }
+
return true;
}