From 8e68f0aad7c3994ddbd1914a48d82c43dd6e7e56 Mon Sep 17 00:00:00 2001 From: James Price Date: Wed, 11 May 2022 13:50:33 +0000 Subject: [PATCH] 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 Reviewed-by: Ben Clayton --- src/tint/resolver/compound_statement_test.cc | 29 ++++++++++++++++++++ src/tint/resolver/resolver.cc | 18 ++++++------ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/tint/resolver/compound_statement_test.cc b/src/tint/resolver/compound_statement_test.cc index 4061a62baf..0444bd3379 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) { } } +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()); + EXPECT_EQ(s->Parent(), s->FindFirstParent()); + EXPECT_EQ(s->Parent(), s->Block()); + } + { + auto* s = Sem().Get(loop->continuing); + ASSERT_NE(s, nullptr); + EXPECT_TRUE(Is(s)); + EXPECT_TRUE(Is(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 4183b447a5..fc7a34df98 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -935,17 +935,15 @@ sem::LoopStatement* Resolver::LoopStatement(const ast::LoopStatement* stmt) { if (stmt->continuing) { Mark(stmt->continuing); - if (!stmt->continuing->Empty()) { - auto* continuing = StatementScope( - stmt->continuing, - builder_->create( - 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( + 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?