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