tint: Resolve empty loop continuing blocks
Otherwise, calling `Sem().Get()` on an empty loop continuing block
will return nullptr, which causes issues when inspecting the semantic
information of ast::BlockStatement nodes generically.
Change-Id: Ib3665b750c96eda02355fa879cf6300b8d69293a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/89721
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/resolver/compound_statement_test.cc b/src/tint/resolver/compound_statement_test.cc
index 4061a62..0444bd3 100644
--- a/src/tint/resolver/compound_statement_test.cc
+++ b/src/tint/resolver/compound_statement_test.cc
@@ -144,6 +144,35 @@
}
}
+TEST_F(ResolverCompoundStatementTest, Loop_EmptyContinuing) {
+ // fn F() {
+ // loop {
+ // break;
+ // continuing {
+ // }
+ // }
+ // }
+ auto* brk = Break();
+ auto* loop = Loop(Block(brk), Block());
+ Func("F", {}, ty.void_(), {loop});
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ {
+ auto* s = Sem().Get(loop);
+ ASSERT_NE(s, nullptr);
+ EXPECT_TRUE(s->Is<sem::LoopStatement>());
+ EXPECT_EQ(s->Parent(), s->FindFirstParent<sem::FunctionBlockStatement>());
+ EXPECT_EQ(s->Parent(), s->Block());
+ }
+ {
+ auto* s = Sem().Get(loop->continuing);
+ ASSERT_NE(s, nullptr);
+ EXPECT_TRUE(Is<sem::LoopContinuingBlockStatement>(s));
+ EXPECT_TRUE(Is<sem::LoopStatement>(s->Parent()->Parent()));
+ }
+}
+
TEST_F(ResolverCompoundStatementTest, ForLoop) {
// fn F() {
// for (var i : u32; true; i = i + 1u) {
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 4183b44..fc7a34d 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -935,17 +935,15 @@
if (stmt->continuing) {
Mark(stmt->continuing);
- if (!stmt->continuing->Empty()) {
- auto* continuing = StatementScope(
- stmt->continuing,
- builder_->create<sem::LoopContinuingBlockStatement>(
- stmt->continuing, current_compound_statement_, current_function_),
- [&] { return Statements(stmt->continuing->statements); });
- if (!continuing) {
- return false;
- }
- behaviors.Add(continuing->Behaviors());
+ auto* continuing = StatementScope(
+ stmt->continuing,
+ builder_->create<sem::LoopContinuingBlockStatement>(
+ stmt->continuing, current_compound_statement_, current_function_),
+ [&] { return Statements(stmt->continuing->statements); });
+ if (!continuing) {
+ return false;
}
+ behaviors.Add(continuing->Behaviors());
}
if (behaviors.Contains(sem::Behavior::kBreak)) { // Does the loop exit?