• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "libabckit/include/cpp/abckit_cpp.h"
17 #include "helpers/helpers.h"
18 #include "helpers/helpers_runtime.h"
19 #include "libabckit/src/logger.h"
20 
21 #include <gtest/gtest.h>
22 #include <string>
23 #include <vector>
24 
25 namespace {
26 
27 class GTestAssertErrorHandler final : public abckit::IErrorHandler {
28 public:
HandleError(abckit::Exception && err)29     void HandleError(abckit::Exception &&err) override
30     {
31         EXPECT_TRUE(false) << "Abckit expection raised: " << err.what();
32     }
33 };
34 
35 }  // namespace
36 
37 namespace libabckit::test {
38 
39 class AbckitScenarioCppTestClean : public ::testing::Test {};
40 
FindRunFunc(const abckit::File * file)41 static abckit::core::Function FindRunFunc(const abckit::File *file)
42 {
43     std::vector<abckit::core::Function> functions;
44     for (auto &module : file->GetModules()) {
45         for (auto &klass : module.GetClasses()) {
46             for (auto &function : klass.GetAllMethods()) {
47                 functions.push_back(function);
48             }
49         }
50         for (auto &function : module.GetTopLevelFunctions()) {
51             functions.push_back(function);
52         }
53     }
54 
55     abckit::core::Function runFunc;
56     for (auto &func : functions) {
57         if (func.GetName() == "run") {
58             runFunc = func;
59             break;
60         }
61     }
62 
63     return runFunc;
64 }
65 
66 // Test: test-kind=scenario, abc-kind=ArkTS1, category=positive, extension=cpp
TEST_F(AbckitScenarioCppTestClean,LibAbcKitTestDynamicAddTryCatchClean)67 TEST_F(AbckitScenarioCppTestClean, LibAbcKitTestDynamicAddTryCatchClean)
68 {
69     const std::string inputPath = ABCKIT_ABC_DIR "clean_scenarios/cpp_api/dynamic/add_try_catch/add_try_catch.abc";
70     auto output = helpers::ExecuteDynamicAbc(inputPath, "add_try_catch");
71     EXPECT_TRUE(helpers::Match(output, "THROW\n"));
72 
73     abckit::File file(inputPath, std::make_unique<GTestAssertErrorHandler>());
74 
75     auto runFunc = FindRunFunc(&file);
76     ASSERT_TRUE(runFunc);
77 
78     abckit::Graph graph = runFunc.CreateGraph();
79     abckit::BasicBlock startBB = graph.GetStartBb();
80     abckit::BasicBlock endBB = graph.GetEndBb();
81     abckit::BasicBlock bb = startBB.GetSuccs()[0];
82     abckit::Instruction initInst = bb.GetFirstInst();
83     abckit::Instruction prevRetInst = bb.GetLastInst().GetPrev();
84     abckit::BasicBlock tryBegin = bb.SplitBlockAfterInstruction(initInst, true);
85     abckit::BasicBlock tryEnd = prevRetInst.GetBasicBlock().SplitBlockAfterInstruction(prevRetInst, true);
86 
87     // Fill catch block
88     abckit::BasicBlock catchBlock = graph.CreateEmptyBb();
89     abckit::Instruction catchPhi = catchBlock.CreateCatchPhi();
90     abckit::Instruction print = graph.DynIsa().CreateTryldglobalbyname("print");
91     abckit::Instruction callArg = graph.DynIsa().CreateCallarg1(print, catchPhi);
92     catchBlock.AddInstBack(print).AddInstBack(callArg);
93 
94     abckit::BasicBlock epilogueBB = endBB.GetPreds()[0];
95     abckit::Instruction retInst = epilogueBB.GetLastInst();
96     abckit::Instruction firstPhiInput = retInst.GetInput(0);
97     abckit::Instruction secondPhiInput = graph.DynIsa().CreateLdfalse();
98     bb.AddInstBack(secondPhiInput);
99     abckit::Instruction phiInst = epilogueBB.CreatePhi(firstPhiInput, secondPhiInput);
100     retInst.SetInput(0, phiInst);
101 
102     graph.InsertTryCatch(tryBegin, tryEnd, catchBlock, catchBlock);
103 
104     runFunc.SetGraph(graph);
105 
106     const std::string modifiedPath =
107         ABCKIT_ABC_DIR "clean_scenarios/cpp_api/dynamic/add_try_catch/add_try_catch_modified.abc";
108     file.WriteAbc(modifiedPath);
109 
110     output = helpers::ExecuteDynamicAbc(modifiedPath, "add_try_catch");
111     EXPECT_TRUE(helpers::Match(output,
112                                "THROW\n"
113                                "Error: DUMMY_ERROR\n"
114                                "false\n"));
115 }
116 
117 }  // namespace libabckit::test
118