• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <array>
17 #include "../tests/test_helper.h"
18 #include "defect_scan_aux_api.h"
19 
20 namespace panda::defect_scan_aux::test {
21 class DefectScanAuxTest {
22 public:
DefectScanAuxTest(std::string_view abc_filename)23     explicit DefectScanAuxTest(std::string_view abc_filename)
24     {
25         abc_file_ = AbcFile::Open(abc_filename);
26         TestHelper::ExpectTrue(abc_file_ != nullptr);
27     }
28 
29     ~DefectScanAuxTest() = default;
30 
GetAbcFileInstance() const31     const std::unique_ptr<const AbcFile> &GetAbcFileInstance() const
32     {
33         return abc_file_;
34     }
35 
CheckFunction(std::string_view func_name) const36     const Function *CheckFunction(std::string_view func_name) const
37     {
38         auto func0 = abc_file_->GetFunctionByName(func_name);
39         TestHelper::ExpectTrue(func0 != nullptr);
40         TestHelper::ExpectEqual(func0->GetFunctionName(), func_name);
41         TestHelper::ExpectTrue(func0->GetAbcFileInstance() == abc_file_.get());
42         return func0;
43     }
44 
ContainDefinedFunction(const Function * par_func,std::string_view func_name) const45     bool ContainDefinedFunction(const Function *par_func, std::string_view func_name) const
46     {
47         size_t df_cnt0 = par_func->GetDefinedFunctionCount();
48         for (size_t i = 0; i < df_cnt0; ++i) {
49             auto df = par_func->GetDefinedFunctionByIndex(i);
50             if (df->GetFunctionName() == func_name) {
51                 TestHelper::ExpectTrue(df->GetParentFunction() == par_func);
52                 return true;
53             }
54         }
55         return false;
56     }
57 
ContainMemberFunction(const Class * class0,std::string_view func_name) const58     bool ContainMemberFunction(const Class *class0, std::string_view func_name) const
59     {
60         size_t mf_func_count = class0->GetMemberFunctionCount();
61         for (size_t i = 0; i < mf_func_count; ++i) {
62             auto mf = class0->GetMemberFunctionByIndex(i);
63             if (mf->GetFunctionName() == func_name) {
64                 TestHelper::ExpectTrue(class0->GetMemberFunctionByName(func_name) == mf);
65                 return true;
66             }
67         }
68 
69         auto par_class = class0->GetParentClass();
70         if (par_class != nullptr) {
71             return ContainMemberFunction(par_class, func_name);
72         }
73         return false;
74     }
75 
CheckClass(std::string_view class_name) const76     const Class *CheckClass(std::string_view class_name) const
77     {
78         auto *class0 = abc_file_->GetClassByName(class_name);
79         TestHelper::ExpectTrue(class0 != nullptr);
80         TestHelper::ExpectEqual(class0->GetClassName(), class_name);
81         TestHelper::ExpectTrue(class0->GetAbcFileInstance() == abc_file_.get());
82         size_t mf_func_count = class0->GetMemberFunctionCount();
83         TestHelper::ExpectTrue(mf_func_count >= 1);
84         auto mf_func0 = class0->GetMemberFunctionByIndex(0);
85         TestHelper::ExpectTrue(abc_file_->GetFunctionByName(class_name) == mf_func0);
86         TestHelper::ExpectTrue(class0->GetMemberFunctionByName(class_name) == mf_func0);
87         TestHelper::ExpectTrue(mf_func0->GetClass() == class0);
88         CheckFunction(class_name);
89         return class0;
90     }
91 
92 private:
93     std::unique_ptr<const AbcFile> abc_file_ {nullptr};
94 };
95 }  // namespace panda::defect_scan_aux::test
96 
97 // TODO(wangyantian): use the test framework to refactor these codes
98 using TestHelper = panda::defect_scan_aux::test::TestHelper;
99 using Inst = panda::defect_scan_aux::Inst;
100 using InstType = panda::defect_scan_aux::InstType;
101 using DefectScanAuxTest = panda::defect_scan_aux::test::DefectScanAuxTest;
main()102 int main()
103 {
104     constexpr size_t TESTCASE_NUM = 5;
105     constexpr std::array<std::string_view, TESTCASE_NUM> TEST_CASE_LIST = {
106         "defectscanaux_tests/unittest/module_info_test.abc", "defectscanaux_tests/unittest/define_info_test.abc",
107         "defectscanaux_tests/unittest/callee_info_test.abc", "defectscanaux_tests/unittest/debug_info_test.abc",
108         "defectscanaux_tests/unittest/graph_test.abc",
109 
110     };
111 
112     std::cout << "===== [libark_defect_scan_aux] Running Unittest =====" << std::endl;
113     {
114         constexpr size_t MODULE_INFO_TEST_INDEX = 0;
115         std::cout << "    --- Running Testcase: " << TEST_CASE_LIST[MODULE_INFO_TEST_INDEX] << " ---" << std::endl;
116         DefectScanAuxTest ds_test(TEST_CASE_LIST[MODULE_INFO_TEST_INDEX]);
117         auto &abc_file = ds_test.GetAbcFileInstance();
118         size_t def_func_cnt = abc_file->GetDefinedFunctionCount();
119         TestHelper::ExpectEqual(def_func_cnt, 8);
120         size_t def_class_cnt = abc_file->GetDefinedClassCount();
121         TestHelper::ExpectEqual(def_class_cnt, 2);
122 
123         // check module info
124         TestHelper::ExpectTrue(abc_file->IsModule());
125         // check exported class
126         std::string inter_name0 = abc_file->GetInternalNameByExportName("UInput");
127         TestHelper::ExpectEqual(inter_name0, "UserInput");
128         auto ex_class = abc_file->GetExportClassByExportName("UInput");
129         TestHelper::ExpectEqual(ex_class->GetClassName(), "#2#UserInput");
130         ds_test.CheckClass("#2#UserInput");
131         size_t mf_func_count0 = ex_class->GetMemberFunctionCount();
132         TestHelper::ExpectEqual(mf_func_count0, 2);
133         auto mf_func0_1 = ex_class->GetMemberFunctionByIndex(1);
134         TestHelper::ExpectEqual(mf_func0_1->GetFunctionName(), "getText");
135         TestHelper::ExpectTrue(mf_func0_1->GetClass() == ex_class);
136         ds_test.CheckFunction("getText");
137         auto par_class = ex_class->GetParentClass();
138         TestHelper::ExpectTrue(par_class != nullptr);
139         TestHelper::ExpectEqual(par_class->GetClassName(), "#1#InnerUserInput");
140         ds_test.CheckClass("#1#InnerUserInput");
141         size_t mf_func_count1 = par_class->GetMemberFunctionCount();
142         TestHelper::ExpectEqual(mf_func_count1, 2);
143         auto mf_func1_1 = par_class->GetMemberFunctionByIndex(1);
144         TestHelper::ExpectEqual(mf_func1_1->GetFunctionName(), "getTextBase");
145         TestHelper::ExpectTrue(mf_func1_1->GetClass() == par_class);
146         ds_test.CheckFunction("getTextBase");
147 
148         // check exported func
149         // func3
150         std::string inter_name1 = abc_file->GetInternalNameByExportName("exFunc3");
151         TestHelper::ExpectEqual(inter_name1, "func3");
152         auto ex_func1 = abc_file->GetExportFunctionByExportName("exFunc3");
153         TestHelper::ExpectEqual(ex_func1->GetFunctionName(), "func3");
154         ds_test.CheckFunction("func3");
155         // func1
156         std::string inter_name2 = abc_file->GetInternalNameByExportName("default");
157         TestHelper::ExpectEqual(inter_name2, "func1");
158         auto ex_func2 = abc_file->GetExportFunctionByExportName("default");
159         TestHelper::ExpectEqual(ex_func2->GetFunctionName(), "func1");
160         ds_test.CheckFunction(inter_name2);
161         // func2
162         std::string inter_name3 = abc_file->GetInternalNameByExportName("func2");
163         TestHelper::ExpectEqual(inter_name3, "func2");
164         auto ex_func3 = abc_file->GetExportFunctionByExportName("func2");
165         TestHelper::ExpectEqual(ex_func3->GetFunctionName(), "func2");
166         ds_test.CheckFunction(inter_name3);
167 
168         // GetModuleNameByInternalName
169         std::string mod_name0 = abc_file->GetModuleNameByInternalName("var1");
170         TestHelper::ExpectEqual(mod_name0, "./mod1");
171         std::string mod_name1 = abc_file->GetModuleNameByInternalName("ns");
172         TestHelper::ExpectEqual(mod_name1, "./mod2");
173         std::string mod_name2 = abc_file->GetModuleNameByInternalName("var3");
174         TestHelper::ExpectEqual(mod_name2, "../mod3");
175         std::string mod_name3 = abc_file->GetModuleNameByInternalName("local_var4");
176         TestHelper::ExpectEqual(mod_name3, "../../mod4");
177 
178         // GetImportNameByInternalName
179         std::string im_name0 = abc_file->GetImportNameByInternalName("var1");
180         TestHelper::ExpectEqual(im_name0, "default");
181         std::string im_name1 = abc_file->GetImportNameByInternalName("var3");
182         TestHelper::ExpectEqual(im_name1, "var3");
183         std::string im_name2 = abc_file->GetImportNameByInternalName("local_var4");
184         TestHelper::ExpectEqual(im_name2, "var4");
185         // GetImportNameByExportName
186         std::string ind_im_name0 = abc_file->GetImportNameByExportName("v");
187         TestHelper::ExpectEqual(ind_im_name0, "v5");
188         std::string ind_im_name1 = abc_file->GetImportNameByExportName("foo");
189         TestHelper::ExpectEqual(ind_im_name1, "foo");
190         // GetModuleNameByExportName
191         std::string ind_mod_name0 = abc_file->GetModuleNameByExportName("v");
192         TestHelper::ExpectEqual(ind_mod_name0, "./mod5");
193         std::string ind_mod_name1 = abc_file->GetModuleNameByExportName("foo");
194         TestHelper::ExpectEqual(ind_mod_name1, "../../mod7");
195         std::cout << "    --- Pass ---" << std::endl << std::endl;
196     }
197 
198     {
199         constexpr size_t DEFINE_INFO_TEST_INDEX = 1;
200         std::cout << "    --- Running Testcase: " << TEST_CASE_LIST[DEFINE_INFO_TEST_INDEX] << " ---" << std::endl;
201         DefectScanAuxTest ds_test(TEST_CASE_LIST[DEFINE_INFO_TEST_INDEX]);
202         auto &abc_file = ds_test.GetAbcFileInstance();
203         TestHelper::ExpectTrue(abc_file->IsModule());
204         size_t def_func_cnt = abc_file->GetDefinedFunctionCount();
205         TestHelper::ExpectEqual(def_func_cnt, 30);
206         size_t def_class_cnt = abc_file->GetDefinedClassCount();
207         TestHelper::ExpectEqual(def_class_cnt, 10);
208 
209         // check each defined func
210         // func_main_0
211         auto f0 = ds_test.CheckFunction("func_main_0");
212         TestHelper::ExpectTrue(f0->GetClass() == nullptr);
213         TestHelper::ExpectTrue(f0->GetParentFunction() == nullptr);
214         size_t dc_cnt0 = f0->GetDefinedClassCount();
215         TestHelper::ExpectEqual(dc_cnt0, 2);
216         TestHelper::ExpectEqual(f0->GetDefinedClassByIndex(0)->GetClassName(), "#1#Bar");
217         TestHelper::ExpectEqual(f0->GetDefinedClassByIndex(1)->GetClassName(), "#6#ExampleClass1");
218         size_t df_cnt0 = f0->GetDefinedFunctionCount();
219         TestHelper::ExpectEqual(df_cnt0, 12);
220         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "func1"));
221         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "func2"));
222         TestHelper::ExpectFalse(ds_test.ContainDefinedFunction(f0, "func3"));
223         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "func6"));
224         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "getName"));
225         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "setName"));
226         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "func9"));
227         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "func10"));
228         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f0, "func17"));
229         // func2
230         auto f1 = ds_test.CheckFunction("func2");
231         TestHelper::ExpectEqual(f1->GetArgCount(), 5);
232         size_t df_cnt1 = f1->GetDefinedFunctionCount();
233         TestHelper::ExpectEqual(df_cnt1, 2);
234         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f1, "func4"));
235         // func10
236         auto f2 = ds_test.CheckFunction("func10");
237         TestHelper::ExpectEqual(f2->GetArgCount(), 3);
238         size_t dc_cnt2 = f2->GetDefinedClassCount();
239         TestHelper::ExpectEqual(dc_cnt2, 2);
240         TestHelper::ExpectEqual(f2->GetDefinedClassByIndex(0)->GetClassName(), "#2#Bar");
241         TestHelper::ExpectEqual(f2->GetDefinedClassByIndex(1)->GetClassName(), "#3#Bar2");
242         size_t df_cnt2 = f2->GetDefinedFunctionCount();
243         TestHelper::ExpectEqual(df_cnt2, 7);
244         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f2, "baseFoo1"));
245         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f2, "func12"));
246         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f2, "#4#"));
247         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f2, "#5#"));
248         TestHelper::ExpectTrue(ds_test.ContainDefinedFunction(f2, "func15"));
249 
250         // check each defined class
251         // #1#Bar
252         auto class0 = ds_test.CheckClass("#1#Bar");
253         TestHelper::ExpectTrue(class0->GetParentClass() == nullptr);
254         TestHelper::ExpectTrue(class0->GetDefineFunction() == f0);
255         size_t mf_count0 = class0->GetMemberFunctionCount();
256         TestHelper::ExpectEqual(mf_count0, 5);
257         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class0, "func6"));
258         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class0, "getName"));
259         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class0, "setName"));
260         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class0, "func9"));
261         // #3#Bar2
262         auto class1 = ds_test.CheckClass("#3#Bar2");
263         TestHelper::ExpectTrue(class1->GetParentClass() != nullptr);
264         TestHelper::ExpectTrue(class1->GetDefineFunction() == abc_file->GetFunctionByName("func10"));
265         size_t mf_count1 = class1->GetMemberFunctionCount();
266         TestHelper::ExpectEqual(mf_count1, 5);
267         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class1, "baseFoo1"));
268         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class1, "func12"));
269         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class1, "func15"));
270         // #8#ExampleClass2
271         auto class2 = ds_test.CheckClass("#8#ExampleClass2");
272         TestHelper::ExpectTrue(class2->GetParentClass() == abc_file->GetClassByName("#7#ExampleClass1"));
273         TestHelper::ExpectFalse(ds_test.ContainMemberFunction(class2, "func17"));
274         TestHelper::ExpectTrue(ds_test.ContainMemberFunction(class2, "func19"));
275         // #9#ExtendService
276         auto class3 = ds_test.CheckClass("#9#ExtendService");
277         TestHelper::ExpectTrue(class3->GetParentClass() == nullptr);
278         TestHelper::ExpectEqual(class3->GetParentClassName(), "BaseService");
279         TestHelper::ExpectEqual(class3->GetParClassExternalModuleName(), "../base/service");
280         TestHelper::ExpectTrue(class3->GetParClassGlobalVarName().empty());
281         // #10#ExtendPhoneService
282         auto class4 = ds_test.CheckClass("#10#ExtendPhoneService");
283         TestHelper::ExpectTrue(class4->GetParentClass() == nullptr);
284         TestHelper::ExpectEqual(class4->GetParentClassName(), "PhoneService");
285         TestHelper::ExpectEqual(class4->GetParClassExternalModuleName(), "../mod1");
286         TestHelper::ExpectTrue(class4->GetParClassGlobalVarName().empty());
287         // #11#ExtendDataSource
288         auto class5 = ds_test.CheckClass("#11#ExtendDataSource");
289         TestHelper::ExpectTrue(class5->GetParentClass() == nullptr);
290         TestHelper::ExpectEqual(class5->GetParentClassName(), "BasicDataSource");
291         TestHelper::ExpectTrue(class5->GetParClassExternalModuleName().empty());
292         TestHelper::ExpectEqual(class5->GetParClassGlobalVarName(), "globalvar");
293         // #12#ExtendDataItem
294         auto class6 = ds_test.CheckClass("#12#ExtendDataItem");
295         TestHelper::ExpectTrue(class6->GetParentClass() == nullptr);
296         TestHelper::ExpectEqual(class6->GetParentClassName(), "DataItem");
297         TestHelper::ExpectTrue(class6->GetParClassExternalModuleName().empty());
298         TestHelper::ExpectEqual(class6->GetParClassGlobalVarName(), "globalvar2.Data");
299         std::cout << "    --- Pass ---" << std::endl << std::endl;
300     }
301 
302     {
303         constexpr size_t CALLEE_INFO_TEST_INDEX = 2;
304         std::cout << "    --- Running Testcase: " << TEST_CASE_LIST[CALLEE_INFO_TEST_INDEX] << " ---" << std::endl;
305         DefectScanAuxTest ds_test(TEST_CASE_LIST[CALLEE_INFO_TEST_INDEX]);
306         auto &abc_file = ds_test.GetAbcFileInstance();
307         TestHelper::ExpectTrue(abc_file->IsModule());
308         size_t def_func_cnt = abc_file->GetDefinedFunctionCount();
309         TestHelper::ExpectEqual(def_func_cnt, 19);
310         size_t def_class_cnt = abc_file->GetDefinedClassCount();
311         TestHelper::ExpectEqual(def_class_cnt, 2);
312 
313         // check callee info of each func
314         // foo
315         auto f0 = abc_file->GetFunctionByName("foo");
316         size_t ci_cnt0 = f0->GetCalleeInfoCount();
317         TestHelper::ExpectEqual(ci_cnt0, 6);
318         auto ci0_0 = f0->GetCalleeInfoByIndex(0);
319         TestHelper::ExpectTrue(f0->GetCalleeInfoByCallInst(ci0_0->GetCallInst()) == ci0_0);
320         TestHelper::ExpectTrue(ci0_0->IsCalleeDefinite());
321         TestHelper::ExpectEqual(ci0_0->GetCalleeArgCount(), 1);
322         TestHelper::ExpectTrue(ci0_0->GetCaller() == f0);
323         TestHelper::ExpectTrue(ci0_0->GetCallee() == abc_file->GetFunctionByName("func2"));
324         auto ci0_1 = f0->GetCalleeInfoByIndex(1);
325         TestHelper::ExpectEqual(f0->GetCalleeInfoByCallInst(ci0_1->GetCallInst()), ci0_1);
326         TestHelper::ExpectFalse(ci0_1->IsCalleeDefinite());
327         TestHelper::ExpectEqual(ci0_1->GetCalleeArgCount(), 1);
328         TestHelper::ExpectTrue(ci0_1->GetCallee() == nullptr);
329         TestHelper::ExpectEqual(ci0_1->GetFunctionName(), "log");
330         TestHelper::ExpectEqual(ci0_1->GetGlobalVarName(), "console");
331         auto ci0_2 = f0->GetCalleeInfoByIndex(2);
332         TestHelper::ExpectFalse(ci0_2->IsCalleeDefinite());
333         TestHelper::ExpectEqual(ci0_2->GetCalleeArgCount(), 1);
334         TestHelper::ExpectTrue(ci0_2->GetCallee() == nullptr);
335         TestHelper::ExpectEqual(ci0_2->GetFunctionName(), "logd");
336         TestHelper::ExpectEqual(ci0_2->GetGlobalVarName(), "globalvar.hilog");
337         auto ci0_3 = f0->GetCalleeInfoByIndex(3);
338         TestHelper::ExpectTrue(ci0_3->IsCalleeDefinite());
339         TestHelper::ExpectTrue(ci0_3->GetCallee() == abc_file->GetFunctionByName("func2"));
340         auto ci0_4 = f0->GetCalleeInfoByIndex(4);
341         TestHelper::ExpectTrue(ci0_4->IsCalleeDefinite());
342         TestHelper::ExpectEqual(ci0_4->GetCalleeArgCount(), 2);
343         TestHelper::ExpectTrue(ci0_4->GetCallee() == abc_file->GetFunctionByName("func1"));
344         auto ci0_5 = f0->GetCalleeInfoByIndex(5);
345         TestHelper::ExpectFalse(ci0_5->IsCalleeDefinite());
346         TestHelper::ExpectEqual(ci0_5->GetFunctionName(), "bar");
347         // foo1
348         auto f1 = abc_file->GetFunctionByName("foo1");
349         size_t ci_cnt1 = f1->GetCalleeInfoCount();
350         TestHelper::ExpectEqual(ci_cnt1, 3);
351         auto ci1_0 = f1->GetCalleeInfoByIndex(0);
352         TestHelper::ExpectTrue(ci1_0->IsCalleeDefinite());
353         TestHelper::ExpectTrue(ci1_0->GetCallee() == abc_file->GetFunctionByName("fn"));
354         auto ci1_1 = f1->GetCalleeInfoByIndex(1);
355         TestHelper::ExpectTrue(ci1_1->IsCalleeDefinite());
356         TestHelper::ExpectTrue(ci1_1->GetCallee() == abc_file->GetFunctionByName("fn"));
357         auto ci1_2 = f1->GetCalleeInfoByIndex(2);
358         TestHelper::ExpectFalse(ci1_2->IsCalleeDefinite());
359         TestHelper::ExpectEqual(ci1_2->GetFunctionName(), "bind");
360         // #2#ColorPoint
361         auto f2 = abc_file->GetFunctionByName("#2#ColorPoint");
362         size_t ci_cnt2 = f2->GetCalleeInfoCount();
363         TestHelper::ExpectEqual(ci_cnt2, 1);
364         auto ci2_0 = f2->GetCalleeInfoByIndex(0);
365         TestHelper::ExpectTrue(ci2_0->IsCalleeDefinite());
366         TestHelper::ExpectTrue(ci2_0->GetClass() == abc_file->GetClassByName("#1#Point"));
367         TestHelper::ExpectTrue(ci2_0->GetCallee() == abc_file->GetFunctionByName("#1#Point"));
368         // func6
369         auto f3 = abc_file->GetFunctionByName("func6");
370         size_t ci_cnt3 = f3->GetCalleeInfoCount();
371         TestHelper::ExpectEqual(ci_cnt3, 1);
372         auto ci3_0 = f3->GetCalleeInfoByIndex(0);
373         TestHelper::ExpectFalse(ci3_0->IsCalleeDefinite());
374         TestHelper::ExpectEqual(ci3_0->GetFunctionName(), "bar");
375         TestHelper::ExpectEqual(ci3_0->GetExternalModuleName(), "./mod2");
376         // func7
377         auto f4 = abc_file->GetFunctionByName("func7");
378         size_t ci_cnt4 = f4->GetCalleeInfoCount();
379         TestHelper::ExpectEqual(ci_cnt4, 2);
380         auto ci4_0 = f4->GetCalleeInfoByIndex(0);
381         TestHelper::ExpectFalse(ci4_0->IsCalleeDefinite());
382         TestHelper::ExpectEqual(ci4_0->GetCalleeArgCount(), 2);
383         TestHelper::ExpectEqual(ci4_0->GetFunctionName(), "sum");
384         TestHelper::ExpectEqual(ci4_0->GetExternalModuleName(), "../../mod1");
385         auto ci4_1 = f4->GetCalleeInfoByIndex(1);
386         TestHelper::ExpectFalse(ci4_1->IsCalleeDefinite());
387         TestHelper::ExpectEqual(ci4_1->GetCalleeArgCount(), 2);
388         TestHelper::ExpectEqual(ci4_1->GetFunctionName(), "sub");
389         TestHelper::ExpectEqual(ci4_1->GetExternalModuleName(), "../../mod1");
390         // callMemberFunc1
391         auto f5 = abc_file->GetFunctionByName("callMemberFunc1");
392         size_t ci_cnt5 = f5->GetCalleeInfoCount();
393         TestHelper::ExpectEqual(ci_cnt5, 2);
394         auto ci5_0 = f5->GetCalleeInfoByIndex(0);
395         TestHelper::ExpectTrue(ci5_0->IsCalleeDefinite());
396         TestHelper::ExpectTrue(ci5_0->GetClass() != nullptr);
397         TestHelper::ExpectEqual(ci5_0->GetClass(), abc_file->GetClassByName("#1#Point"));
398         TestHelper::ExpectTrue(ci5_0->GetCallee() != nullptr);
399         TestHelper::ExpectEqual(ci5_0->GetCallee(), abc_file->GetFunctionByName("getCoordinateX"));
400         auto ci5_1 = f5->GetCalleeInfoByIndex(1);
401         TestHelper::ExpectTrue(ci5_1->IsCalleeDefinite());
402         TestHelper::ExpectTrue(ci5_1->GetClass() != nullptr);
403         TestHelper::ExpectEqual(ci5_1->GetClass(), abc_file->GetClassByName("#1#Point"));
404         TestHelper::ExpectTrue(ci5_1->GetCallee() != nullptr);
405         TestHelper::ExpectEqual(ci5_1->GetCallee(), abc_file->GetFunctionByName("setCoordinateX"));
406         // callMemberFunc2
407         auto f6 = abc_file->GetFunctionByName("callMemberFunc2");
408         size_t ci_cnt6 = f6->GetCalleeInfoCount();
409         TestHelper::ExpectEqual(ci_cnt6, 2);
410         auto ci6_0 = f6->GetCalleeInfoByIndex(0);
411         TestHelper::ExpectTrue(ci6_0->IsCalleeDefinite());
412         TestHelper::ExpectTrue(ci6_0->GetClass() != nullptr);
413         TestHelper::ExpectEqual(ci6_0->GetClass(), abc_file->GetClassByName("#1#Point"));
414         TestHelper::ExpectTrue(ci6_0->GetCallee() != nullptr);
415         TestHelper::ExpectEqual(ci6_0->GetCallee(), abc_file->GetFunctionByName("plus"));
416         auto ci6_1 = f6->GetCalleeInfoByIndex(1);
417         TestHelper::ExpectFalse(ci6_1->IsCalleeDefinite());
418         TestHelper::ExpectEqual(ci6_1->GetFunctionName(), "sub");
419         TestHelper::ExpectEqual(ci6_1->GetExternalModuleName(), "");
420         TestHelper::ExpectEqual(ci6_1->GetGlobalVarName(), "");
421         // callExClassMemberFunc1
422         auto f7 = abc_file->GetFunctionByName("callExClassMemberFunc1");
423         size_t ci_cnt7 = f7->GetCalleeInfoCount();
424         TestHelper::ExpectEqual(ci_cnt7, 1);
425         auto ci7_0 = f7->GetCalleeInfoByIndex(0);
426         TestHelper::ExpectFalse(ci7_0->IsCalleeDefinite());
427         TestHelper::ExpectTrue(ci7_0->GetClass() == nullptr);
428         TestHelper::ExpectEqual(ci7_0->GetFunctionName(), "makePhoneCall");
429         TestHelper::ExpectEqual(ci7_0->GetExternalModuleName(), "../../mod1");
430         TestHelper::ExpectEqual(ci7_0->GetGlobalVarName(), "");
431         std::cout << "    --- Pass ---" << std::endl << std::endl;
432     }
433 
434     {
435         constexpr size_t DEBUG_INFO_TEST_INDEX = 3;
436         std::cout << "    --- Running Testcase: " << TEST_CASE_LIST[DEBUG_INFO_TEST_INDEX] << " ---" << std::endl;
437         DefectScanAuxTest ds_test(TEST_CASE_LIST[DEBUG_INFO_TEST_INDEX]);
438         auto &abc_file = ds_test.GetAbcFileInstance();
439         TestHelper::ExpectFalse(abc_file->IsModule());
440 
441         // check debug info, whether the line number obtained from call inst is correct
442         auto f0 = abc_file->GetFunctionByName("foo");
443         TestHelper::ExpectEqual(f0->GetCalleeInfoCount(), 3);
444         auto ci0_0 = f0->GetCalleeInfoByIndex(0);
445         // callarg0
446         TestHelper::ExpectEqual(abc_file->GetLineNumberByInst(f0, ci0_0->GetCallInst()), 33);
447         auto ci0_1 = f0->GetCalleeInfoByIndex(1);
448         // callspread
449         TestHelper::ExpectEqual(abc_file->GetLineNumberByInst(f0, ci0_1->GetCallInst()), 37);
450         auto ci0_2 = f0->GetCalleeInfoByIndex(2);
451         // callirange
452         TestHelper::ExpectEqual(abc_file->GetLineNumberByInst(f0, ci0_2->GetCallInst()), 39);
453         // ctor of Data
454         auto f1 = abc_file->GetFunctionByName("#2#Data");
455         TestHelper::ExpectEqual(f1->GetCalleeInfoCount(), 1);
456         auto ci1_0 = f1->GetCalleeInfoByIndex(0);
457         // supercall
458         TestHelper::ExpectEqual(abc_file->GetLineNumberByInst(f1, ci1_0->GetCallInst()), 59);
459         // bar
460         auto f2 = abc_file->GetFunctionByName("bar");
461         TestHelper::ExpectEqual(f2->GetCalleeInfoCount(), 2);
462         auto ci2_0 = f2->GetCalleeInfoByIndex(0);
463         // callithisrange
464         TestHelper::ExpectEqual(abc_file->GetLineNumberByInst(f2, ci2_0->GetCallInst()), 69);
465         auto ci2_1 = f2->GetCalleeInfoByIndex(1);
466         // callithisrange
467         TestHelper::ExpectEqual(abc_file->GetLineNumberByInst(f2, ci2_1->GetCallInst()), 74);
468         std::cout << "    --- Pass ---" << std::endl << std::endl;
469     }
470 
471     {
472         constexpr size_t GRAPH_TEST_INDEX = 4;
473         std::cout << "    --- Running Testcase: " << TEST_CASE_LIST[GRAPH_TEST_INDEX] << " ---" << std::endl;
474         DefectScanAuxTest ds_test(TEST_CASE_LIST[GRAPH_TEST_INDEX]);
475         auto f0 = ds_test.CheckFunction("foo");
476 
477         // check api of graph
478         auto &graph = f0->GetGraph();
479         auto bb_list = graph.GetBasicBlockList();
480         TestHelper::ExpectEqual(bb_list.size(), 8);
481         TestHelper::ExpectEqual(bb_list.front(), graph.GetStartBasicBlock());
482         TestHelper::ExpectEqual(bb_list.back(), graph.GetEndBasicBlock());
483         std::unordered_map<InstType, uint32_t> inst_cnt_table;
484         graph.VisitAllInstructions([&inst_cnt_table](const Inst &inst) {
485             auto type = inst.GetType();
486             inst_cnt_table.insert_or_assign(type, inst_cnt_table[type] + 1);
487         });
488         uint32_t newobj_cnt = inst_cnt_table[InstType::NEWOBJRANGE_IMM8_IMM8_V8] +
489                               inst_cnt_table[InstType::NEWOBJRANGE_IMM16_IMM8_V8] +
490                               inst_cnt_table[InstType::WIDE_NEWOBJRANGE_PREF_IMM16_V8];
491         TestHelper::ExpectEqual(newobj_cnt, 2);
492         uint32_t ldlex_cnt = inst_cnt_table[InstType::LDLEXVAR_IMM4_IMM4] +
493                              inst_cnt_table[InstType::LDLEXVAR_IMM8_IMM8] +
494                              inst_cnt_table[InstType::WIDE_LDLEXVAR_PREF_IMM16_IMM16];
495         TestHelper::ExpectEqual(ldlex_cnt, 7);
496         TestHelper::ExpectEqual(
497             inst_cnt_table[InstType::LDOBJBYNAME_IMM8_ID16] + inst_cnt_table[InstType::LDOBJBYNAME_IMM16_ID16], 4);
498         TestHelper::ExpectEqual(inst_cnt_table[InstType::CALLTHIS1_IMM8_V8_V8], 3);
499         TestHelper::ExpectEqual(inst_cnt_table[InstType::CALLTHIS2_IMM8_V8_V8_V8], 1);
500         TestHelper::ExpectEqual(inst_cnt_table[InstType::DEFINEFUNC_IMM8_ID16_IMM8] +
501                                     inst_cnt_table[InstType::DEFINEFUNC_IMM16_ID16_IMM8],
502                                 1);
503         TestHelper::ExpectEqual(inst_cnt_table[InstType::CALLARG0_IMM8], 1);
504         TestHelper::ExpectEqual(inst_cnt_table[InstType::CALLARG1_IMM8_V8], 1);
505         TestHelper::ExpectEqual(inst_cnt_table[InstType::LDEXTERNALMODULEVAR_IMM8] +
506                                     inst_cnt_table[InstType::WIDE_LDEXTERNALMODULEVAR_PREF_IMM16],
507                                 1);
508         TestHelper::ExpectEqual(inst_cnt_table[InstType::GETMODULENAMESPACE_IMM8] +
509                                     inst_cnt_table[InstType::WIDE_GETMODULENAMESPACE_PREF_IMM16],
510                                 0);
511         TestHelper::ExpectEqual(inst_cnt_table[InstType::OPCODE_PARAMETER], 5);
512 
513         // check api of basic block
514         auto bb0 = graph.GetStartBasicBlock();
515         TestHelper::ExpectEqual(bb0.GetPredBlocks().size(), 0);
516         TestHelper::ExpectEqual(bb0.GetSuccBlocks().size(), 1);
517         auto bb1 = bb0.GetSuccBlocks()[0];
518         TestHelper::ExpectEqual(bb1.GetPredBlocks().size(), 1);
519         TestHelper::ExpectEqual(bb1.GetPredBlocks()[0], bb0);
520         auto bb1_succ_bb = bb1.GetSuccBlocks();
521         TestHelper::ExpectEqual(bb1_succ_bb.size(), 2);
522         TestHelper::ExpectTrue(
523             (bb1_succ_bb[0].GetSuccBlocks().size() == 2 && bb1_succ_bb[1].GetSuccBlocks().size() == 1) ||
524             (bb1_succ_bb[0].GetSuccBlocks().size() == 1 && bb1_succ_bb[1].GetSuccBlocks().size() == 2));
525         auto bb2 = graph.GetEndBasicBlock();
526         auto bb2_pred_bb = bb2.GetPredBlocks();
527         TestHelper::ExpectEqual(bb2_pred_bb.size(), 2);
528         auto bb3 = bb2_pred_bb[0];
529         auto bb4 = bb2_pred_bb[1];
530         if (bb3.GetPredBlocks().size() < bb4.GetPredBlocks().size()) {
531             std::swap(bb3, bb4);
532         }
533         TestHelper::ExpectEqual(bb3.GetPredBlocks().size(), 2);
534         TestHelper::ExpectEqual(bb4.GetPredBlocks().size(), 1);
535         TestHelper::ExpectEqual(bb4.GetPredBlocks()[0], bb1);
536 
537         // check api of inst
538         size_t ci_cnt = f0->GetCalleeInfoCount();
539         TestHelper::ExpectEqual(ci_cnt, 6);
540         auto ci0 = f0->GetCalleeInfoByIndex(ci_cnt - 1);
541         auto call_inst0 = ci0->GetCallInst();
542         auto call_inst0_ins = call_inst0.GetInputInsts();
543         TestHelper::ExpectEqual(call_inst0_ins.size(), 4);
544         auto call_inst0_in1_type = call_inst0_ins[1].GetType();
545         TestHelper::ExpectEqual(call_inst0_in1_type, InstType::CALLARG0_IMM8);
546         TestHelper::ExpectEqual(call_inst0_ins[1].GetUserInsts().size(), 1);
547         TestHelper::ExpectEqual(call_inst0_ins[1].GetUserInsts()[0], call_inst0);
548         auto call_inst0_in2_type = call_inst0_ins[2].GetType();
549         TestHelper::ExpectEqual(call_inst0_in2_type, InstType::OPCODE_PARAMETER);
550         TestHelper::ExpectEqual(call_inst0_ins[2].GetArgIndex(), 4);
551         auto param1_usrs = call_inst0_ins[2].GetUserInsts();
552         TestHelper::ExpectTrue(std::find(param1_usrs.begin(), param1_usrs.end(), call_inst0) != param1_usrs.end());
553         auto call_inst0_in3_type = call_inst0_ins[3].GetType();
554         TestHelper::ExpectTrue(call_inst0_in3_type == InstType::LDOBJBYNAME_IMM8_ID16 ||
555                                 call_inst0_in3_type == InstType::LDOBJBYNAME_IMM16_ID16);
556         TestHelper::ExpectEqual(call_inst0_ins[3].GetUserInsts().size(), 1);
557         TestHelper::ExpectEqual(call_inst0_ins[3].GetUserInsts()[0], call_inst0);
558 
559         auto ci1 = f0->GetCalleeInfoByIndex(ci_cnt - 2);
560         auto call_inst1 = ci1->GetCallInst();
561         auto call_inst1_ins = call_inst1.GetInputInsts();
562         TestHelper::ExpectEqual(call_inst1_ins.size(), 2);
563         auto call_inst1_in0_type = call_inst1_ins[1].GetType();
564         TestHelper::ExpectTrue(call_inst1_in0_type == InstType::LDEXTERNALMODULEVAR_IMM8 ||
565                                 call_inst1_in0_type == InstType::WIDE_LDEXTERNALMODULEVAR_PREF_IMM16);
566         TestHelper::ExpectEqual(call_inst1_ins[1].GetUserInsts().size(), 2);
567         TestHelper::ExpectTrue((call_inst1_ins[1].GetUserInsts()[0] == call_inst1) ||
568                                (call_inst1_ins[1].GetUserInsts()[1] == call_inst1));
569         auto phi_inst = call_inst1_ins[0];
570         TestHelper::ExpectEqual(phi_inst.GetType(), InstType::OPCODE_PHI);
571         auto phi_inst_ins = phi_inst.GetInputInsts();
572         TestHelper::ExpectEqual(phi_inst_ins.size(), 2);
573         auto phi_inst_in0 = phi_inst_ins[0];
574         auto phi_inst_in1 = phi_inst_ins[1];
575         if (phi_inst_in0.GetType() != InstType::OPCODE_PARAMETER) {
576             std::swap(phi_inst_in0, phi_inst_in1);
577         }
578         TestHelper::ExpectEqual(phi_inst_in0.GetType(), InstType::OPCODE_PARAMETER);
579         TestHelper::ExpectEqual(phi_inst_in0.GetArgIndex(), 3);
580         auto param0_usrs = phi_inst_in0.GetUserInsts();
581         TestHelper::ExpectTrue(std::find(param0_usrs.begin(), param0_usrs.end(), phi_inst) != param0_usrs.end());
582         TestHelper::ExpectEqual(phi_inst_in1.GetType(), InstType::ADD2_IMM8_V8);
583         auto add2_inst_ins = phi_inst_in1.GetInputInsts();
584         TestHelper::ExpectEqual(add2_inst_ins.size(), 2);
585         TestHelper::ExpectEqual(add2_inst_ins[0].GetType(), InstType::OPCODE_PARAMETER);
586         TestHelper::ExpectEqual(add2_inst_ins[1].GetType(), InstType::OPCODE_PARAMETER);
587         std::cout << "    --- Pass ---" << std::endl;
588     }
589     std::cout << "===== [libark_defect_scan_aux] Unittest Pass =====" << std::endl;
590 
591     return 0;
592 }