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