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