1 /**
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
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
16 #include "cfg_test.h"
17
18 namespace ark::es2panda::compiler {
19
TEST_F(CFGTest,do_while_statement_01)20 TEST_F(CFGTest, do_while_statement_01)
21 {
22 char const *text = R"(
23 function main() {
24 let i: number = 0;
25 do {
26 i++;
27 } while (i < 10);
28 let a: number = 42;
29 }
30 )";
31
32 CONTEXT(ES2PANDA_STATE_CHECKED, text)
33 {
34 CFG *cfg = GetCfg();
35 ASSERT_TRUE(cfg != nullptr);
36
37 const ArenaSet<compiler::CFG::BasicBlock *> basicBlocks = cfg->GetBasicBlocks();
38 ASSERT_EQ(basicBlocks.size(), EXPECTED_FOUR);
39
40 auto bb1 = GetBBByID(basicBlocks, ID_01);
41 ASSERT_NE(bb1, nullptr);
42
43 auto bb2 = GetBBByID(basicBlocks, ID_02);
44 ASSERT_NE(bb2, nullptr);
45
46 auto bb3 = GetBBByID(basicBlocks, ID_03);
47 ASSERT_NE(bb3, nullptr);
48
49 auto bb4 = GetBBByID(basicBlocks, ID_04);
50 ASSERT_NE(bb4, nullptr);
51
52 ASSERT_EQ(bb1->GetSuccessors().size(), EXPECTED_ONE);
53 ASSERT_EQ(bb1->GetPredecessors().size(), EXPECTED_ZERO);
54 ASSERT_EQ(bb2->GetSuccessors().size(), EXPECTED_ONE);
55 ASSERT_EQ(bb2->GetPredecessors().size(), EXPECTED_TWO);
56 ASSERT_EQ(bb3->GetSuccessors().size(), EXPECTED_TWO);
57 ASSERT_EQ(bb3->GetPredecessors().size(), EXPECTED_ONE);
58
59 ASSERT_EQ(bb4->GetSuccessors().size(), EXPECTED_ZERO);
60 auto bb4Predecessors = bb4->GetPredecessors();
61 ASSERT_EQ(bb4Predecessors.size(), EXPECTED_ONE);
62 ASSERT_EQ(bb4Predecessors[0], bb3);
63 }
64 }
65
TEST_F(CFGTest,do_while_statement_with_break)66 TEST_F(CFGTest, do_while_statement_with_break)
67 {
68 char const *text = R"(
69 function main() {
70 let i: number = 1;
71 do {
72 if (i % 2 == 0) {
73 break;
74 }
75 i++;
76 } while (i < 10);
77 let a: number = 42;
78 }
79 )";
80
81 CONTEXT(ES2PANDA_STATE_CHECKED, text)
82 {
83 CFG *cfg = GetCfg();
84 ASSERT_TRUE(cfg != nullptr);
85
86 const ArenaSet<compiler::CFG::BasicBlock *> basicBlocks = cfg->GetBasicBlocks();
87 ASSERT_EQ(basicBlocks.size(), EXPECTED_FIVE);
88
89 auto bb1 = GetBBByID(basicBlocks, ID_01);
90 ASSERT_NE(bb1, nullptr);
91
92 auto bb2 = GetBBByID(basicBlocks, ID_02);
93 ASSERT_NE(bb2, nullptr);
94
95 auto bb3 = GetBBByID(basicBlocks, ID_03);
96 ASSERT_NE(bb3, nullptr);
97
98 auto bb4 = GetBBByID(basicBlocks, ID_04);
99 ASSERT_NE(bb4, nullptr);
100
101 auto bb7 = GetBBByID(basicBlocks, ID_07);
102 ASSERT_NE(bb7, nullptr);
103
104 ASSERT_EQ(bb1->GetSuccessors().size(), EXPECTED_ONE);
105 ASSERT_EQ(bb1->GetPredecessors().size(), EXPECTED_ZERO);
106
107 ASSERT_EQ(bb2->GetSuccessors().size(), EXPECTED_TWO);
108 ASSERT_EQ(bb2->GetPredecessors().size(), EXPECTED_TWO);
109
110 ASSERT_EQ(bb3->GetSuccessors().size(), EXPECTED_TWO);
111 ASSERT_EQ(bb3->GetPredecessors().size(), EXPECTED_ONE);
112
113 ASSERT_EQ(bb4->GetSuccessors().size(), EXPECTED_ZERO);
114
115 auto bb4Predecessors = bb4->GetPredecessors();
116 ASSERT_EQ(bb4Predecessors.size(), EXPECTED_TWO);
117 ASSERT_EQ(bb4Predecessors[0], bb3);
118 ASSERT_EQ(bb4Predecessors[1], bb2);
119
120 ASSERT_EQ(bb7->GetSuccessors().size(), EXPECTED_ONE);
121 ASSERT_EQ(bb7->GetPredecessors().size(), EXPECTED_TWO); // NOTE: Should be 1, needs to be fixed
122 }
123 }
124
TEST_F(CFGTest,do_while_statement_with_continue)125 TEST_F(CFGTest, do_while_statement_with_continue)
126 {
127 char const *text = R"(
128 function main() {
129 let i: number = 1;
130 do {
131 i++;
132 if (i % 2 == 0) {
133 continue;
134 }
135 let b = i * 3;
136 } while (i < 10);
137 let a: number = 42;
138 }
139 )";
140
141 CONTEXT(ES2PANDA_STATE_CHECKED, text)
142 {
143 CFG *cfg = GetCfg();
144 ASSERT_TRUE(cfg != nullptr);
145
146 const ArenaSet<compiler::CFG::BasicBlock *> basicBlocks = cfg->GetBasicBlocks();
147 ASSERT_EQ(basicBlocks.size(), EXPECTED_FIVE);
148
149 auto bb1 = GetBBByID(basicBlocks, ID_01);
150 ASSERT_NE(bb1, nullptr);
151
152 auto bb2 = GetBBByID(basicBlocks, ID_02);
153 ASSERT_NE(bb2, nullptr);
154
155 auto bb3 = GetBBByID(basicBlocks, ID_03);
156 ASSERT_NE(bb3, nullptr);
157
158 auto bb4 = GetBBByID(basicBlocks, ID_04);
159 ASSERT_NE(bb4, nullptr);
160
161 auto bb7 = GetBBByID(basicBlocks, ID_07);
162 ASSERT_NE(bb7, nullptr);
163
164 ASSERT_EQ(bb1->GetSuccessors().size(), EXPECTED_ONE);
165 ASSERT_EQ(bb1->GetPredecessors().size(), EXPECTED_ZERO);
166
167 ASSERT_EQ(bb2->GetSuccessors().size(), EXPECTED_TWO);
168 ASSERT_EQ(bb2->GetPredecessors().size(), EXPECTED_TWO);
169
170 ASSERT_EQ(bb3->GetSuccessors().size(), EXPECTED_TWO);
171 ASSERT_EQ(bb3->GetPredecessors().size(), EXPECTED_TWO);
172
173 ASSERT_EQ(bb4->GetSuccessors().size(), EXPECTED_ZERO);
174
175 auto bb4Predecessors = bb4->GetPredecessors();
176 ASSERT_EQ(bb4Predecessors.size(), EXPECTED_ONE);
177 ASSERT_EQ(bb4Predecessors[0], bb3);
178
179 auto bb7Successors = bb7->GetSuccessors();
180 ASSERT_EQ(bb7Successors.size(), EXPECTED_ONE);
181 ASSERT_EQ(bb7Successors[0], bb3);
182 auto bb7Predecessors = bb7->GetPredecessors();
183 ASSERT_EQ(bb7Predecessors.size(), EXPECTED_TWO); // NOTE: Should be 1, needs to be fixed
184 }
185 }
186
187 } // namespace ark::es2panda::compiler
188