1 /**
2 * Copyright (c) 2024-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 "libabckit/include/c/abckit.h"
17 #include "libabckit/include/c/metadata_core.h"
18 #include "libabckit/include/c/ir_core.h"
19
20 #include "helpers/helpers_runtime.h"
21 #include "helpers/helpers.h"
22
23 #include <gtest/gtest.h>
24
25 namespace libabckit::test {
26
27 namespace {
28 auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
29 auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
30 auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
31 auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0);
32 auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0);
33
TransformIrNegativeInst(AbckitGraph * graph,AbckitFile * file,AbckitCoreClass * classA)34 void TransformIrNegativeInst(AbckitGraph *graph, AbckitFile *file, AbckitCoreClass *classA)
35 {
36 AbckitInst *initObj = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_INITOBJECT);
37 ASSERT_NE(initObj, nullptr);
38 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
39
40 AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
41 ASSERT_NE(ret, nullptr);
42 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
43
44 auto *type = g_implM->createReferenceType(file, classA);
45 ASSERT_NE(type, nullptr);
46 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
47
48 AbckitInst *isInstance = g_statG->iCreateIsInstance(graph, initObj, type);
49 ASSERT_NE(isInstance, nullptr);
50 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
51
52 AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 1);
53 g_implG->iSetInput(isInstance, idx, 0);
54 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
55
56 g_implG->iInsertAfter(isInstance, initObj);
57 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
58
59 helpers::ReplaceInst(ret, g_statG->iCreateReturn(graph, isInstance));
60 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
61 }
62
TransformIrNegativeBB(AbckitGraph * graph)63 void TransformIrNegativeBB(AbckitGraph *graph)
64 {
65 AbckitBasicBlock *bbEnd = g_implG->gGetEndBasicBlock(graph);
66 AbckitBasicBlock *bb2 = g_implG->gGetBasicBlock(graph, 2);
67 g_implG->bbAppendSuccBlock(bbEnd, bb2);
68 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
69 }
70
TransformIrNegativeBinInst(AbckitGraph * graph)71 void TransformIrNegativeBinInst(AbckitGraph *graph)
72 {
73 AbckitInst *loadString = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_LOADSTRING);
74 ASSERT_NE(loadString, nullptr);
75 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
76
77 AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN);
78 ASSERT_NE(ret, nullptr);
79 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
80
81 AbckitInst *idx = g_implG->gFindOrCreateConstantI64(graph, 5);
82 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
83
84 AbckitInst *addInst = g_statG->iCreateAdd(graph, loadString, idx);
85 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
86
87 g_implG->iInsertBefore(addInst, ret);
88 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
89 }
90
91 } // namespace
92
93 class LibAbcKitGraphVerifierTest : public ::testing::Test {};
94
95 // Test: test-kind=internal, abc-kind=ArkTS2, category=internal
TEST_F(LibAbcKitGraphVerifierTest,LibAbcKitTestGraphVerifierInst)96 TEST_F(LibAbcKitGraphVerifierTest, LibAbcKitTestGraphVerifierInst)
97 {
98 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_verifier/graph_verifier.abc";
99 auto output = helpers::ExecuteStaticAbc(INPUT_PATH, "graph_verifier/ETSGLOBAL", "main");
100 EXPECT_TRUE(helpers::Match(output, "123\nfalse\n"));
101
102 AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
103 auto *method = helpers::FindMethodByName(file, "foo");
104 ASSERT_NE(method, nullptr);
105 auto *module = g_implI->functionGetModule(method);
106 helpers::ClassByNameContext classCtxFinder = {nullptr, "A"};
107 g_implI->moduleEnumerateClasses(module, &classCtxFinder, helpers::ClassByNameFinder);
108 ASSERT_NE(classCtxFinder.klass, nullptr);
109
110 AbckitGraph *graph = g_implI->createGraphFromFunction(method);
111 TransformIrNegativeInst(graph, g_implI->functionGetFile(method), classCtxFinder.klass);
112 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
113 g_implM->functionSetGraph(method, graph);
114 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
115 g_impl->destroyGraph(graph);
116
117 g_impl->closeFile(file);
118 }
119
120 // Test: test-kind=internal, abc-kind=ArkTS2, category=internal
TEST_F(LibAbcKitGraphVerifierTest,LibAbcKitTestGraphVerifierBB)121 TEST_F(LibAbcKitGraphVerifierTest, LibAbcKitTestGraphVerifierBB)
122 {
123 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_verifier/graph_verifier.abc";
124 auto output = helpers::ExecuteStaticAbc(INPUT_PATH, "graph_verifier/ETSGLOBAL", "main");
125 EXPECT_TRUE(helpers::Match(output, "123\nfalse\n"));
126
127 AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
128 auto *method = helpers::FindMethodByName(file, "bar");
129 ASSERT_NE(method, nullptr);
130
131 AbckitGraph *graph = g_implI->createGraphFromFunction(method);
132 TransformIrNegativeBB(graph);
133 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
134 g_implM->functionSetGraph(method, graph);
135 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
136 g_impl->destroyGraph(graph);
137
138 g_impl->closeFile(file);
139 }
140
141 // Test: test-kind=internal, abc-kind=ArkTS2, category=internal
TEST_F(LibAbcKitGraphVerifierTest,DISABLED_LibAbcKitTestGraphVerifierBinInst)142 TEST_F(LibAbcKitGraphVerifierTest, DISABLED_LibAbcKitTestGraphVerifierBinInst)
143 {
144 constexpr auto INPUT_PATH = ABCKIT_ABC_DIR "ut/ir_core/graph_verifier/graph_verifier.abc";
145 auto output = helpers::ExecuteStaticAbc(INPUT_PATH, "graph_verifier/ETSGLOBAL", "main");
146 EXPECT_TRUE(helpers::Match(output, "123\nfalse\n"));
147
148 AbckitFile *file = g_impl->openAbc(INPUT_PATH, strlen(INPUT_PATH));
149 auto *method = helpers::FindMethodByName(file, "foo");
150 ASSERT_NE(method, nullptr);
151
152 AbckitGraph *graph = g_implI->createGraphFromFunction(method);
153 TransformIrNegativeBinInst(graph);
154 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR);
155 g_implM->functionSetGraph(method, graph);
156 ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_BAD_ARGUMENT);
157 g_impl->destroyGraph(graph);
158
159 g_impl->closeFile(file);
160 }
161
162 } // namespace libabckit::test
163