• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/resolver/resolver.h"
16 
17 #include "gtest/gtest.h"
18 #include "src/resolver/resolver_test_helper.h"
19 #include "src/sem/expression.h"
20 
21 namespace tint {
22 namespace resolver {
23 namespace {
24 
25 class ResolverBehaviorTest : public ResolverTest {
26  protected:
SetUp()27   void SetUp() override {
28     // Create a function called 'DiscardOrNext' which returns an i32, and has
29     // the behavior of {Discard, Return}, which when called, will have the
30     // behavior {Discard, Next}.
31     Func("DiscardOrNext", {}, ty.i32(),
32          {
33              If(true, Block(Discard())),
34              Return(1),
35          });
36   }
37 };
38 
TEST_F(ResolverBehaviorTest,ExprBinaryOp_LHS)39 TEST_F(ResolverBehaviorTest, ExprBinaryOp_LHS) {
40   auto* stmt = Decl(Var("lhs", ty.i32(), Add(Call("DiscardOrNext"), 1)));
41   WrapInFunction(stmt);
42 
43   ASSERT_TRUE(r()->Resolve()) << r()->error();
44 
45   auto* sem = Sem().Get(stmt);
46   EXPECT_EQ(sem->Behaviors(),
47             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
48 }
49 
TEST_F(ResolverBehaviorTest,ExprBinaryOp_RHS)50 TEST_F(ResolverBehaviorTest, ExprBinaryOp_RHS) {
51   auto* stmt = Decl(Var("lhs", ty.i32(), Add(1, Call("DiscardOrNext"))));
52   WrapInFunction(stmt);
53 
54   ASSERT_TRUE(r()->Resolve()) << r()->error();
55 
56   auto* sem = Sem().Get(stmt);
57   EXPECT_EQ(sem->Behaviors(),
58             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
59 }
60 
TEST_F(ResolverBehaviorTest,ExprBitcastOp)61 TEST_F(ResolverBehaviorTest, ExprBitcastOp) {
62   auto* stmt = Decl(Var("lhs", ty.u32(), Bitcast<u32>(Call("DiscardOrNext"))));
63   WrapInFunction(stmt);
64 
65   ASSERT_TRUE(r()->Resolve()) << r()->error();
66 
67   auto* sem = Sem().Get(stmt);
68   EXPECT_EQ(sem->Behaviors(),
69             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
70 }
71 
TEST_F(ResolverBehaviorTest,ExprIndex_Arr)72 TEST_F(ResolverBehaviorTest, ExprIndex_Arr) {
73   Func("ArrayDiscardOrNext", {}, ty.array<i32, 4>(),
74        {
75            If(true, Block(Discard())),
76            Return(Construct(ty.array<i32, 4>())),
77        });
78 
79   auto* stmt =
80       Decl(Var("lhs", ty.i32(), IndexAccessor(Call("ArrayDiscardOrNext"), 1)));
81   WrapInFunction(stmt);
82 
83   ASSERT_TRUE(r()->Resolve()) << r()->error();
84 
85   auto* sem = Sem().Get(stmt);
86   EXPECT_EQ(sem->Behaviors(),
87             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
88 }
89 
TEST_F(ResolverBehaviorTest,ExprIndex_Idx)90 TEST_F(ResolverBehaviorTest, ExprIndex_Idx) {
91   auto* stmt =
92       Decl(Var("lhs", ty.i32(), IndexAccessor("arr", Call("DiscardOrNext"))));
93   WrapInFunction(Decl(Var("arr", ty.array<i32, 4>())),  //
94                  stmt);
95 
96   ASSERT_TRUE(r()->Resolve()) << r()->error();
97 
98   auto* sem = Sem().Get(stmt);
99   EXPECT_EQ(sem->Behaviors(),
100             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
101 }
102 
TEST_F(ResolverBehaviorTest,ExprUnaryOp)103 TEST_F(ResolverBehaviorTest, ExprUnaryOp) {
104   auto* stmt = Decl(Var("lhs", ty.i32(),
105                         create<ast::UnaryOpExpression>(
106                             ast::UnaryOp::kComplement, Call("DiscardOrNext"))));
107   WrapInFunction(stmt);
108 
109   ASSERT_TRUE(r()->Resolve()) << r()->error();
110 
111   auto* sem = Sem().Get(stmt);
112   EXPECT_EQ(sem->Behaviors(),
113             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
114 }
115 
TEST_F(ResolverBehaviorTest,StmtAssign)116 TEST_F(ResolverBehaviorTest, StmtAssign) {
117   auto* stmt = Assign("lhs", "rhs");
118   WrapInFunction(Decl(Var("lhs", ty.i32())),  //
119                  Decl(Var("rhs", ty.i32())),  //
120                  stmt);
121 
122   ASSERT_TRUE(r()->Resolve()) << r()->error();
123 
124   auto* sem = Sem().Get(stmt);
125   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
126 }
127 
TEST_F(ResolverBehaviorTest,StmtAssign_LHSDiscardOrNext)128 TEST_F(ResolverBehaviorTest, StmtAssign_LHSDiscardOrNext) {
129   auto* stmt = Assign(IndexAccessor("lhs", Call("DiscardOrNext")), 1);
130   WrapInFunction(Decl(Var("lhs", ty.array<i32, 4>())),  //
131                  stmt);
132 
133   ASSERT_TRUE(r()->Resolve()) << r()->error();
134 
135   auto* sem = Sem().Get(stmt);
136   EXPECT_EQ(sem->Behaviors(),
137             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
138 }
139 
TEST_F(ResolverBehaviorTest,StmtAssign_RHSDiscardOrNext)140 TEST_F(ResolverBehaviorTest, StmtAssign_RHSDiscardOrNext) {
141   auto* stmt = Assign("lhs", Call("DiscardOrNext"));
142   WrapInFunction(Decl(Var("lhs", ty.i32())),  //
143                  stmt);
144 
145   ASSERT_TRUE(r()->Resolve()) << r()->error();
146 
147   auto* sem = Sem().Get(stmt);
148   EXPECT_EQ(sem->Behaviors(),
149             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
150 }
151 
TEST_F(ResolverBehaviorTest,StmtBlockEmpty)152 TEST_F(ResolverBehaviorTest, StmtBlockEmpty) {
153   auto* stmt = Block();
154   WrapInFunction(stmt);
155 
156   ASSERT_TRUE(r()->Resolve()) << r()->error();
157 
158   auto* sem = Sem().Get(stmt);
159   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
160 }
161 
TEST_F(ResolverBehaviorTest,StmtBlockSingleStmt)162 TEST_F(ResolverBehaviorTest, StmtBlockSingleStmt) {
163   auto* stmt = Block(Discard());
164   WrapInFunction(stmt);
165 
166   ASSERT_TRUE(r()->Resolve()) << r()->error();
167 
168   auto* sem = Sem().Get(stmt);
169   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
170 }
171 
TEST_F(ResolverBehaviorTest,StmtCallReturn)172 TEST_F(ResolverBehaviorTest, StmtCallReturn) {
173   Func("f", {}, ty.void_(), {Return()});
174   auto* stmt = CallStmt(Call("f"));
175   WrapInFunction(stmt);
176 
177   ASSERT_TRUE(r()->Resolve()) << r()->error();
178 
179   auto* sem = Sem().Get(stmt);
180   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
181 }
182 
TEST_F(ResolverBehaviorTest,StmtCallFuncDiscard)183 TEST_F(ResolverBehaviorTest, StmtCallFuncDiscard) {
184   Func("f", {}, ty.void_(), {Discard()});
185   auto* stmt = CallStmt(Call("f"));
186   WrapInFunction(stmt);
187 
188   ASSERT_TRUE(r()->Resolve()) << r()->error();
189 
190   auto* sem = Sem().Get(stmt);
191   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
192 }
193 
TEST_F(ResolverBehaviorTest,StmtCallFuncMayDiscard)194 TEST_F(ResolverBehaviorTest, StmtCallFuncMayDiscard) {
195   auto* stmt = For(Decl(Var("v", ty.i32(), Call("DiscardOrNext"))), nullptr,
196                    nullptr, Block(Break()));
197   WrapInFunction(stmt);
198 
199   ASSERT_TRUE(r()->Resolve()) << r()->error();
200 
201   auto* sem = Sem().Get(stmt);
202   EXPECT_EQ(sem->Behaviors(),
203             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
204 }
205 
TEST_F(ResolverBehaviorTest,StmtBreak)206 TEST_F(ResolverBehaviorTest, StmtBreak) {
207   auto* stmt = Break();
208   WrapInFunction(Loop(Block(stmt)));
209 
210   ASSERT_TRUE(r()->Resolve()) << r()->error();
211 
212   auto* sem = Sem().Get(stmt);
213   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kBreak);
214 }
215 
TEST_F(ResolverBehaviorTest,StmtContinue)216 TEST_F(ResolverBehaviorTest, StmtContinue) {
217   auto* stmt = Continue();
218   WrapInFunction(Loop(Block(stmt)));
219 
220   ASSERT_TRUE(r()->Resolve()) << r()->error();
221 
222   auto* sem = Sem().Get(stmt);
223   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kContinue);
224 }
225 
TEST_F(ResolverBehaviorTest,StmtDiscard)226 TEST_F(ResolverBehaviorTest, StmtDiscard) {
227   auto* stmt = Discard();
228   WrapInFunction(stmt);
229 
230   ASSERT_TRUE(r()->Resolve()) << r()->error();
231 
232   auto* sem = Sem().Get(stmt);
233   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
234 }
235 
TEST_F(ResolverBehaviorTest,StmtForLoopEmpty)236 TEST_F(ResolverBehaviorTest, StmtForLoopEmpty) {
237   auto* stmt = For(nullptr, nullptr, nullptr, Block());
238   WrapInFunction(stmt);
239 
240   ASSERT_TRUE(r()->Resolve()) << r()->error();
241 
242   auto* sem = Sem().Get(stmt);
243   EXPECT_TRUE(sem->Behaviors().Empty());
244 }
245 
TEST_F(ResolverBehaviorTest,StmtForLoopBreak)246 TEST_F(ResolverBehaviorTest, StmtForLoopBreak) {
247   auto* stmt = For(nullptr, nullptr, nullptr, Block(Break()));
248   WrapInFunction(stmt);
249 
250   ASSERT_TRUE(r()->Resolve()) << r()->error();
251 
252   auto* sem = Sem().Get(stmt);
253   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
254 }
255 
TEST_F(ResolverBehaviorTest,StmtForLoopContinue)256 TEST_F(ResolverBehaviorTest, StmtForLoopContinue) {
257   auto* stmt = For(nullptr, nullptr, nullptr, Block(Continue()));
258   WrapInFunction(stmt);
259 
260   ASSERT_TRUE(r()->Resolve()) << r()->error();
261 
262   auto* sem = Sem().Get(stmt);
263   EXPECT_TRUE(sem->Behaviors().Empty());
264 }
265 
TEST_F(ResolverBehaviorTest,StmtForLoopDiscard)266 TEST_F(ResolverBehaviorTest, StmtForLoopDiscard) {
267   auto* stmt = For(nullptr, nullptr, nullptr, Block(Discard()));
268   WrapInFunction(stmt);
269 
270   ASSERT_TRUE(r()->Resolve()) << r()->error();
271 
272   auto* sem = Sem().Get(stmt);
273   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
274 }
275 
TEST_F(ResolverBehaviorTest,StmtForLoopReturn)276 TEST_F(ResolverBehaviorTest, StmtForLoopReturn) {
277   auto* stmt = For(nullptr, nullptr, nullptr, Block(Return()));
278   WrapInFunction(stmt);
279 
280   ASSERT_TRUE(r()->Resolve()) << r()->error();
281 
282   auto* sem = Sem().Get(stmt);
283   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kReturn);
284 }
285 
TEST_F(ResolverBehaviorTest,StmtForLoopBreak_InitCallFuncMayDiscard)286 TEST_F(ResolverBehaviorTest, StmtForLoopBreak_InitCallFuncMayDiscard) {
287   auto* stmt = For(Decl(Var("v", ty.i32(), Call("DiscardOrNext"))), nullptr,
288                    nullptr, Block(Break()));
289   WrapInFunction(stmt);
290 
291   ASSERT_TRUE(r()->Resolve()) << r()->error();
292 
293   auto* sem = Sem().Get(stmt);
294   EXPECT_EQ(sem->Behaviors(),
295             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
296 }
297 
TEST_F(ResolverBehaviorTest,StmtForLoopEmpty_InitCallFuncMayDiscard)298 TEST_F(ResolverBehaviorTest, StmtForLoopEmpty_InitCallFuncMayDiscard) {
299   auto* stmt = For(Decl(Var("v", ty.i32(), Call("DiscardOrNext"))), nullptr,
300                    nullptr, Block());
301   WrapInFunction(stmt);
302 
303   ASSERT_TRUE(r()->Resolve()) << r()->error();
304 
305   auto* sem = Sem().Get(stmt);
306   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
307 }
308 
TEST_F(ResolverBehaviorTest,StmtForLoopEmpty_CondTrue)309 TEST_F(ResolverBehaviorTest, StmtForLoopEmpty_CondTrue) {
310   auto* stmt = For(nullptr, true, nullptr, Block());
311   WrapInFunction(stmt);
312 
313   ASSERT_TRUE(r()->Resolve()) << r()->error();
314 
315   auto* sem = Sem().Get(stmt);
316   EXPECT_EQ(sem->Behaviors(), sem::Behaviors(sem::Behavior::kNext));
317 }
318 
TEST_F(ResolverBehaviorTest,StmtForLoopEmpty_CondCallFuncMayDiscard)319 TEST_F(ResolverBehaviorTest, StmtForLoopEmpty_CondCallFuncMayDiscard) {
320   auto* stmt = For(nullptr, Equal(Call("DiscardOrNext"), 1), nullptr, Block());
321   WrapInFunction(stmt);
322 
323   ASSERT_TRUE(r()->Resolve()) << r()->error();
324 
325   auto* sem = Sem().Get(stmt);
326   EXPECT_EQ(sem->Behaviors(),
327             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
328 }
329 
TEST_F(ResolverBehaviorTest,StmtIfTrue_ThenEmptyBlock)330 TEST_F(ResolverBehaviorTest, StmtIfTrue_ThenEmptyBlock) {
331   auto* stmt = If(true, Block());
332   WrapInFunction(stmt);
333 
334   ASSERT_TRUE(r()->Resolve()) << r()->error();
335 
336   auto* sem = Sem().Get(stmt);
337   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
338 }
339 
TEST_F(ResolverBehaviorTest,StmtIfTrue_ThenDiscard)340 TEST_F(ResolverBehaviorTest, StmtIfTrue_ThenDiscard) {
341   auto* stmt = If(true, Block(Discard()));
342   WrapInFunction(stmt);
343 
344   ASSERT_TRUE(r()->Resolve()) << r()->error();
345 
346   auto* sem = Sem().Get(stmt);
347   EXPECT_EQ(sem->Behaviors(),
348             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
349 }
350 
TEST_F(ResolverBehaviorTest,StmtIfTrue_ThenEmptyBlock_ElseDiscard)351 TEST_F(ResolverBehaviorTest, StmtIfTrue_ThenEmptyBlock_ElseDiscard) {
352   auto* stmt = If(true, Block(), Else(Block(Discard())));
353   WrapInFunction(stmt);
354 
355   ASSERT_TRUE(r()->Resolve()) << r()->error();
356 
357   auto* sem = Sem().Get(stmt);
358   EXPECT_EQ(sem->Behaviors(),
359             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
360 }
361 
TEST_F(ResolverBehaviorTest,StmtIfTrue_ThenDiscard_ElseDiscard)362 TEST_F(ResolverBehaviorTest, StmtIfTrue_ThenDiscard_ElseDiscard) {
363   auto* stmt = If(true, Block(Discard()), Else(Block(Discard())));
364   WrapInFunction(stmt);
365 
366   ASSERT_TRUE(r()->Resolve()) << r()->error();
367 
368   auto* sem = Sem().Get(stmt);
369   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
370 }
371 
TEST_F(ResolverBehaviorTest,StmtIfCallFuncMayDiscard_ThenEmptyBlock)372 TEST_F(ResolverBehaviorTest, StmtIfCallFuncMayDiscard_ThenEmptyBlock) {
373   auto* stmt = If(Equal(Call("DiscardOrNext"), 1), Block());
374   WrapInFunction(stmt);
375 
376   ASSERT_TRUE(r()->Resolve()) << r()->error();
377 
378   auto* sem = Sem().Get(stmt);
379   EXPECT_EQ(sem->Behaviors(),
380             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
381 }
382 
TEST_F(ResolverBehaviorTest,StmtIfTrue_ThenEmptyBlock_ElseCallFuncMayDiscard)383 TEST_F(ResolverBehaviorTest, StmtIfTrue_ThenEmptyBlock_ElseCallFuncMayDiscard) {
384   auto* stmt = If(true, Block(),  //
385                   Else(Equal(Call("DiscardOrNext"), 1), Block()));
386   WrapInFunction(stmt);
387 
388   ASSERT_TRUE(r()->Resolve()) << r()->error();
389 
390   auto* sem = Sem().Get(stmt);
391   EXPECT_EQ(sem->Behaviors(),
392             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
393 }
394 
TEST_F(ResolverBehaviorTest,StmtLetDecl)395 TEST_F(ResolverBehaviorTest, StmtLetDecl) {
396   auto* stmt = Decl(Const("v", ty.i32(), Expr(1)));
397   WrapInFunction(stmt);
398 
399   ASSERT_TRUE(r()->Resolve()) << r()->error();
400 
401   auto* sem = Sem().Get(stmt);
402   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
403 }
404 
TEST_F(ResolverBehaviorTest,StmtLetDecl_RHSDiscardOrNext)405 TEST_F(ResolverBehaviorTest, StmtLetDecl_RHSDiscardOrNext) {
406   auto* stmt = Decl(Const("lhs", ty.i32(), Call("DiscardOrNext")));
407   WrapInFunction(stmt);
408 
409   ASSERT_TRUE(r()->Resolve()) << r()->error();
410 
411   auto* sem = Sem().Get(stmt);
412   EXPECT_EQ(sem->Behaviors(),
413             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
414 }
415 
TEST_F(ResolverBehaviorTest,StmtLoopEmpty)416 TEST_F(ResolverBehaviorTest, StmtLoopEmpty) {
417   auto* stmt = Loop(Block());
418   WrapInFunction(stmt);
419 
420   ASSERT_TRUE(r()->Resolve()) << r()->error();
421 
422   auto* sem = Sem().Get(stmt);
423   EXPECT_TRUE(sem->Behaviors().Empty());
424 }
425 
TEST_F(ResolverBehaviorTest,StmtLoopBreak)426 TEST_F(ResolverBehaviorTest, StmtLoopBreak) {
427   auto* stmt = Loop(Block(Break()));
428   WrapInFunction(stmt);
429 
430   ASSERT_TRUE(r()->Resolve()) << r()->error();
431 
432   auto* sem = Sem().Get(stmt);
433   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
434 }
435 
TEST_F(ResolverBehaviorTest,StmtLoopContinue)436 TEST_F(ResolverBehaviorTest, StmtLoopContinue) {
437   auto* stmt = Loop(Block(Continue()));
438   WrapInFunction(stmt);
439 
440   ASSERT_TRUE(r()->Resolve()) << r()->error();
441 
442   auto* sem = Sem().Get(stmt);
443   EXPECT_TRUE(sem->Behaviors().Empty());
444 }
445 
TEST_F(ResolverBehaviorTest,StmtLoopDiscard)446 TEST_F(ResolverBehaviorTest, StmtLoopDiscard) {
447   auto* stmt = Loop(Block(Discard()));
448   WrapInFunction(stmt);
449 
450   ASSERT_TRUE(r()->Resolve()) << r()->error();
451 
452   auto* sem = Sem().Get(stmt);
453   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
454 }
455 
TEST_F(ResolverBehaviorTest,StmtLoopReturn)456 TEST_F(ResolverBehaviorTest, StmtLoopReturn) {
457   auto* stmt = Loop(Block(Return()));
458   WrapInFunction(stmt);
459 
460   ASSERT_TRUE(r()->Resolve()) << r()->error();
461 
462   auto* sem = Sem().Get(stmt);
463   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kReturn);
464 }
465 
TEST_F(ResolverBehaviorTest,StmtLoopEmpty_ContEmpty)466 TEST_F(ResolverBehaviorTest, StmtLoopEmpty_ContEmpty) {
467   auto* stmt = Loop(Block(), Block());
468   WrapInFunction(stmt);
469 
470   ASSERT_TRUE(r()->Resolve()) << r()->error();
471 
472   auto* sem = Sem().Get(stmt);
473   EXPECT_TRUE(sem->Behaviors().Empty());
474 }
475 
TEST_F(ResolverBehaviorTest,StmtLoopEmpty_ContBreak)476 TEST_F(ResolverBehaviorTest, StmtLoopEmpty_ContBreak) {
477   auto* stmt = Loop(Block(), Block(Break()));
478   WrapInFunction(stmt);
479 
480   ASSERT_TRUE(r()->Resolve()) << r()->error();
481 
482   auto* sem = Sem().Get(stmt);
483   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
484 }
485 
TEST_F(ResolverBehaviorTest,StmtReturn)486 TEST_F(ResolverBehaviorTest, StmtReturn) {
487   auto* stmt = Return();
488   WrapInFunction(stmt);
489 
490   ASSERT_TRUE(r()->Resolve()) << r()->error();
491 
492   auto* sem = Sem().Get(stmt);
493   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kReturn);
494 }
495 
TEST_F(ResolverBehaviorTest,StmtReturn_DiscardOrNext)496 TEST_F(ResolverBehaviorTest, StmtReturn_DiscardOrNext) {
497   auto* stmt = Return(Call("DiscardOrNext"));
498   Func("F", {}, ty.i32(), {stmt});
499 
500   ASSERT_TRUE(r()->Resolve()) << r()->error();
501 
502   auto* sem = Sem().Get(stmt);
503   EXPECT_EQ(sem->Behaviors(),
504             sem::Behaviors(sem::Behavior::kReturn, sem::Behavior::kDiscard));
505 }
506 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondTrue_DefaultEmpty)507 TEST_F(ResolverBehaviorTest, StmtSwitch_CondTrue_DefaultEmpty) {
508   auto* stmt = Switch(1, DefaultCase(Block()));
509   WrapInFunction(stmt);
510 
511   ASSERT_TRUE(r()->Resolve()) << r()->error();
512 
513   auto* sem = Sem().Get(stmt);
514   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
515 }
516 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_DefaultEmpty)517 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_DefaultEmpty) {
518   auto* stmt = Switch(1, DefaultCase(Block()));
519   WrapInFunction(stmt);
520 
521   ASSERT_TRUE(r()->Resolve()) << r()->error();
522 
523   auto* sem = Sem().Get(stmt);
524   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
525 }
526 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_DefaultDiscard)527 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_DefaultDiscard) {
528   auto* stmt = Switch(1, DefaultCase(Block(Discard())));
529   WrapInFunction(stmt);
530 
531   ASSERT_TRUE(r()->Resolve()) << r()->error();
532 
533   auto* sem = Sem().Get(stmt);
534   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
535 }
536 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_DefaultReturn)537 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_DefaultReturn) {
538   auto* stmt = Switch(1, DefaultCase(Block(Return())));
539   WrapInFunction(stmt);
540 
541   ASSERT_TRUE(r()->Resolve()) << r()->error();
542 
543   auto* sem = Sem().Get(stmt);
544   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kReturn);
545 }
546 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_Case0Empty_DefaultEmpty)547 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Empty_DefaultEmpty) {
548   auto* stmt = Switch(1, Case(Expr(0), Block()), DefaultCase(Block()));
549   WrapInFunction(stmt);
550 
551   ASSERT_TRUE(r()->Resolve()) << r()->error();
552 
553   auto* sem = Sem().Get(stmt);
554   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
555 }
556 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_Case0Empty_DefaultDiscard)557 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Empty_DefaultDiscard) {
558   auto* stmt = Switch(1, Case(Expr(0), Block()), DefaultCase(Block(Discard())));
559   WrapInFunction(stmt);
560 
561   ASSERT_TRUE(r()->Resolve()) << r()->error();
562 
563   auto* sem = Sem().Get(stmt);
564   EXPECT_EQ(sem->Behaviors(),
565             sem::Behaviors(sem::Behavior::kNext, sem::Behavior::kDiscard));
566 }
567 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_Case0Empty_DefaultReturn)568 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Empty_DefaultReturn) {
569   auto* stmt = Switch(1, Case(Expr(0), Block()), DefaultCase(Block(Return())));
570   WrapInFunction(stmt);
571 
572   ASSERT_TRUE(r()->Resolve()) << r()->error();
573 
574   auto* sem = Sem().Get(stmt);
575   EXPECT_EQ(sem->Behaviors(),
576             sem::Behaviors(sem::Behavior::kNext, sem::Behavior::kReturn));
577 }
578 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_Case0Discard_DefaultEmpty)579 TEST_F(ResolverBehaviorTest, StmtSwitch_CondLiteral_Case0Discard_DefaultEmpty) {
580   auto* stmt = Switch(1, Case(Expr(0), Block(Discard())), DefaultCase(Block()));
581   WrapInFunction(stmt);
582 
583   ASSERT_TRUE(r()->Resolve()) << r()->error();
584 
585   auto* sem = Sem().Get(stmt);
586   EXPECT_EQ(sem->Behaviors(),
587             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
588 }
589 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_Case0Discard_DefaultDiscard)590 TEST_F(ResolverBehaviorTest,
591        StmtSwitch_CondLiteral_Case0Discard_DefaultDiscard) {
592   auto* stmt =
593       Switch(1, Case(Expr(0), Block(Discard())), DefaultCase(Block(Discard())));
594   WrapInFunction(stmt);
595 
596   ASSERT_TRUE(r()->Resolve()) << r()->error();
597 
598   auto* sem = Sem().Get(stmt);
599   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
600 }
601 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_Case0Discard_DefaultReturn)602 TEST_F(ResolverBehaviorTest,
603        StmtSwitch_CondLiteral_Case0Discard_DefaultReturn) {
604   auto* stmt =
605       Switch(1, Case(Expr(0), Block(Discard())), DefaultCase(Block(Return())));
606   WrapInFunction(stmt);
607 
608   ASSERT_TRUE(r()->Resolve()) << r()->error();
609 
610   auto* sem = Sem().Get(stmt);
611   EXPECT_EQ(sem->Behaviors(),
612             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kReturn));
613 }
614 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondLiteral_Case0Discard_Case1Return_DefaultEmpty)615 TEST_F(ResolverBehaviorTest,
616        StmtSwitch_CondLiteral_Case0Discard_Case1Return_DefaultEmpty) {
617   auto* stmt = Switch(1,                                //
618                       Case(Expr(0), Block(Discard())),  //
619                       Case(Expr(1), Block(Return())),   //
620                       DefaultCase(Block()));
621   WrapInFunction(stmt);
622 
623   ASSERT_TRUE(r()->Resolve()) << r()->error();
624 
625   auto* sem = Sem().Get(stmt);
626   EXPECT_EQ(sem->Behaviors(),
627             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext,
628                            sem::Behavior::kReturn));
629 }
630 
TEST_F(ResolverBehaviorTest,StmtSwitch_CondCallFuncMayDiscard_DefaultEmpty)631 TEST_F(ResolverBehaviorTest, StmtSwitch_CondCallFuncMayDiscard_DefaultEmpty) {
632   auto* stmt = Switch(Call("DiscardOrNext"), DefaultCase(Block()));
633   WrapInFunction(stmt);
634 
635   ASSERT_TRUE(r()->Resolve()) << r()->error();
636 
637   auto* sem = Sem().Get(stmt);
638   EXPECT_EQ(sem->Behaviors(),
639             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
640 }
641 
TEST_F(ResolverBehaviorTest,StmtVarDecl)642 TEST_F(ResolverBehaviorTest, StmtVarDecl) {
643   auto* stmt = Decl(Var("v", ty.i32()));
644   WrapInFunction(stmt);
645 
646   ASSERT_TRUE(r()->Resolve()) << r()->error();
647 
648   auto* sem = Sem().Get(stmt);
649   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
650 }
651 
TEST_F(ResolverBehaviorTest,StmtVarDecl_RHSDiscardOrNext)652 TEST_F(ResolverBehaviorTest, StmtVarDecl_RHSDiscardOrNext) {
653   auto* stmt = Decl(Var("lhs", ty.i32(), Call("DiscardOrNext")));
654   WrapInFunction(stmt);
655 
656   ASSERT_TRUE(r()->Resolve()) << r()->error();
657 
658   auto* sem = Sem().Get(stmt);
659   EXPECT_EQ(sem->Behaviors(),
660             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
661 }
662 
663 }  // namespace
664 }  // namespace resolver
665 }  // namespace tint
666