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?