• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "compiler/tests/unit_test.h"
17 #include "irtoc/backend/compiler/dangling_pointers_checker.h"
18 #include "irtoc/backend/function.h"
19 #include "irtoc/backend/irtoc_runtime.h"
20 
21 namespace panda::compiler {
22 class DanglingPointersCheckerTest : public GraphTest {};
23 
24 class RelocationHandlerTest : public panda::irtoc::Function {
25 public:
MakeGraphImpl()26     void MakeGraphImpl() override {};
GetName() const27     const char *GetName() const override
28     {
29         return "Test";
30     };
SetTestExternalFunctions(std::initializer_list<std::string> funcs)31     void SetTestExternalFunctions(std::initializer_list<std::string> funcs)
32     {
33         this->SetExternalFunctions(funcs);
34     }
35 };
36 
37 // NOLINTBEGIN(readability-magic-numbers)
38 
39 // Correct load accumulator from frame with one instruction:
40 //    correct_acc_load  := LoadI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
41 // Correct store into frame with instruction:
42 //    correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test0)43 TEST_F(DanglingPointersCheckerTest, test0)
44 {
45     auto arch = panda::RUNTIME_ARCH;
46     SetGraphArch(arch);
47     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
48         return;
49     }
50     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
51     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
52     RelocationHandlerTest relocationHandler;
53     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
54     GetGraph()->SetRelocationHandler(&relocationHandler);
55     GetGraph()->SetMethod(&relocationHandler);
56     GetGraph()->SetMode(GraphMode::InterpreterEntry());
57 
58     GRAPH(GetGraph())
59     {
60         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
61         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
62         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
63 
64         BASIC_BLOCK(2U, -1L)
65         {
66             INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
67             INST(6U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
68 
69             // store tag
70             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
71             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
72 
73             INST(3U, Opcode::Call).TypeId(0U).ptr();
74             INST(4U, Opcode::ReturnVoid).v0id();
75         }
76     }
77 
78     irtoc::IrtocRuntimeInterface runtime;
79     GetGraph()->SetRuntime(&runtime);
80 
81     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
82 }
83 
84 // Correct load accumulator from frame with two instructions:
85 //    acc_ptr           := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
86 //    correct_acc_load  := LoadI(acc_ptr).Imm(frame_acc_offset).ref
87 // Correct store into frame with instruction:
88 //    correct_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test1)89 TEST_F(DanglingPointersCheckerTest, test1)
90 {
91     auto arch = panda::RUNTIME_ARCH;
92     SetGraphArch(arch);
93     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
94         return;
95     }
96     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
97     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
98     RelocationHandlerTest relocationHandler;
99     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
100     GetGraph()->SetRelocationHandler(&relocationHandler);
101     GetGraph()->SetMethod(&relocationHandler);
102     GetGraph()->SetMode(GraphMode::InterpreterEntry());
103 
104     GRAPH(GetGraph())
105     {
106         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
107         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
108         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
109         CONSTANT(10U, 10U).i64();
110         CONSTANT(11U, 15U).i64();
111 
112         BASIC_BLOCK(2U, -1L)
113         {
114             INST(5U, Opcode::AddI).Inputs(0U).Imm(frameAccOffset).ptr();
115             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
116             INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
117             INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
118 
119             // store tag
120             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
121             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
122 
123             INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
124             INST(4U, Opcode::ReturnVoid).v0id();
125         }
126     }
127 
128     irtoc::IrtocRuntimeInterface runtime;
129     GetGraph()->SetRuntime(&runtime);
130 
131     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
132 }
133 
134 // Incorrect load accumulator from fake frame with two instructions:
135 //    fake_acc_ptr       := AddI(fake_frame).Imm(frame_acc_offset).ptr
136 //    incorrect_acc_load := LoadI(fake_acc_ptr).Imm(0).ref
137 // Correct store into frame with instruction:
138 //    correct_acc_store  := StoreI(LiveIn(frame).ptr, LiveIn(acc).ptr).Imm(frame_acc_offset)
TEST_F(DanglingPointersCheckerTest,test2)139 TEST_F(DanglingPointersCheckerTest, test2)
140 {
141     auto arch = panda::RUNTIME_ARCH;
142     SetGraphArch(arch);
143     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
144         return;
145     }
146     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
147     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
148     RelocationHandlerTest relocationHandler;
149     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
150     GetGraph()->SetRelocationHandler(&relocationHandler);
151     GetGraph()->SetMethod(&relocationHandler);
152     GetGraph()->SetMode(GraphMode::InterpreterEntry());
153 
154     GRAPH(GetGraph())
155     {
156         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
157         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
158         INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
159 
160         BASIC_BLOCK(2U, -1L)
161         {
162             INST(5U, Opcode::AddI).Inputs(1U).Imm(frameAccOffset).ptr();
163             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
164             INST(8U, Opcode::StoreI).u64().Inputs(0U, 1U).Imm(frameAccOffset);
165 
166             // store tag
167             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
168             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
169 
170             INST(3U, Opcode::Call).TypeId(0U).ptr();
171             INST(4U, Opcode::ReturnVoid).v0id();
172         }
173     }
174 
175     irtoc::IrtocRuntimeInterface runtime;
176     GetGraph()->SetRuntime(&runtime);
177 
178     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
179 }
180 
181 // Incorrect load accumulator from fake frame with two instructions:
182 //    fake_acc_ptr        := AddI(fake_frame).Imm(frame_acc_offset).ptr
183 //    incorrect_acc_load  := LoadI(fake_acc_ptr).Imm(0).ref
184 // Incorrect store fake_acc_load into frame with instruction:
185 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, fake_acc_load).Imm(frame_acc_offset)
TEST_F(DanglingPointersCheckerTest,test3)186 TEST_F(DanglingPointersCheckerTest, test3)
187 {
188     auto arch = panda::RUNTIME_ARCH;
189     SetGraphArch(arch);
190     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
191         return;
192     }
193     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
194     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
195     RelocationHandlerTest relocationHandler;
196     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
197     GetGraph()->SetRelocationHandler(&relocationHandler);
198     GetGraph()->SetMethod(&relocationHandler);
199     GetGraph()->SetMode(GraphMode::InterpreterEntry());
200 
201     GRAPH(GetGraph())
202     {
203         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
204         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
205         INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
206 
207         BASIC_BLOCK(2U, -1L)
208         {
209             INST(5U, Opcode::AddI).Inputs(1U).Imm(frameAccOffset).ptr();
210             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
211             INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
212 
213             // store tag
214             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
215             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
216 
217             INST(3U, Opcode::Call).TypeId(0U).ptr();
218             INST(4U, Opcode::ReturnVoid).v0id();
219         }
220     }
221 
222     irtoc::IrtocRuntimeInterface runtime;
223     GetGraph()->SetRuntime(&runtime);
224 
225     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
226 }
227 
228 // Incorrect load accumulator from fake frame with two instructions:
229 //    fake_acc_ptr        := AddI(fake_frame).Imm(frame_acc_offset).ptr
230 //    incorrect_acc_load  := LoadI(fake_acc_ptr).Imm(0).ref
231 // Incorrect store fake_acc_load into frame with instruction:
232 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, fake_acc_load).Imm(frame_acc_offset)
233 // But acc type is integer: LiveIn(acc).u64; so the check is not performed
TEST_F(DanglingPointersCheckerTest,test4)234 TEST_F(DanglingPointersCheckerTest, test4)
235 {
236     auto arch = panda::RUNTIME_ARCH;
237     SetGraphArch(arch);
238     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
239         return;
240     }
241     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
242     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
243     RelocationHandlerTest relocationHandler;
244     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
245     GetGraph()->SetRelocationHandler(&relocationHandler);
246     GetGraph()->SetMethod(&relocationHandler);
247     GetGraph()->SetMode(GraphMode::InterpreterEntry());
248 
249     GRAPH(GetGraph())
250     {
251         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
252         INST(1U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
253         INST(2U, Opcode::LiveIn).i64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
254         INST(10U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
255 
256         BASIC_BLOCK(2U, -1L)
257         {
258             INST(5U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).ptr();
259             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
260             INST(8U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
261 
262             // store tag
263             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
264             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
265 
266             INST(3U, Opcode::Call).TypeId(0U).ptr();
267             INST(4U, Opcode::ReturnVoid).v0id();
268         }
269     }
270 
271     irtoc::IrtocRuntimeInterface runtime;
272     GetGraph()->SetRuntime(&runtime);
273 
274     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
275 }
276 
277 // Correct load accumulator from last frame definition with two instructions:
278 //    last_frame_def    := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
279 //    acc_ptr           := AddI(last_frame_def).Imm(frame_acc_offset).ptr
280 //    correct_acc_load  := LoadI(acc_ptr).Imm(0).ref
281 // Correct store into frame with instruction:
282 //    correct_acc_store := StoreI(last_frame_def, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test5)283 TEST_F(DanglingPointersCheckerTest, test5)
284 {
285     auto arch = panda::RUNTIME_ARCH;
286     SetGraphArch(arch);
287     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
288         return;
289     }
290     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
291     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
292     RelocationHandlerTest relocationHandler;
293     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
294     GetGraph()->SetRelocationHandler(&relocationHandler);
295     GetGraph()->SetMethod(&relocationHandler);
296     GetGraph()->SetMode(GraphMode::InterpreterEntry());
297 
298     GRAPH(GetGraph())
299     {
300         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
301         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
302         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
303         CONSTANT(10U, 10U).i64();
304         CONSTANT(11U, 15U).i64();
305 
306         BASIC_BLOCK(2U, -1L)
307         {
308             INST(8U, Opcode::LoadI).Inputs(0U).ptr().Imm(Frame::GetPrevFrameOffset());
309             INST(5U, Opcode::AddI).Inputs(8U).Imm(frameAccOffset).ptr();
310             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
311             INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
312             INST(9U, Opcode::StoreI).ref().Inputs(8U, 6U).Imm(frameAccOffset);
313 
314             // store tag
315             INST(31U, Opcode::StoreI).u64().Inputs(5U, 2U).Imm(accTagOffset);
316 
317             INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
318             INST(4U, Opcode::ReturnVoid).v0id();
319         }
320     }
321 
322     irtoc::IrtocRuntimeInterface runtime;
323     GetGraph()->SetRuntime(&runtime);
324 
325     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
326 }
327 
328 // Correct load accumulator from last frame definition with one instructions:
329 //    last_frame_def      := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
330 //    correct_acc_load    := LoadI(last_frame_def).Imm(frame_acc_offset).ref
331 // Incorrect store into old frame with instruction:
332 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test6)333 TEST_F(DanglingPointersCheckerTest, test6)
334 {
335     auto arch = panda::RUNTIME_ARCH;
336     SetGraphArch(arch);
337     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
338         return;
339     }
340     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
341     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
342     RelocationHandlerTest relocationHandler;
343     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
344     GetGraph()->SetRelocationHandler(&relocationHandler);
345     GetGraph()->SetMethod(&relocationHandler);
346     GetGraph()->SetMode(GraphMode::InterpreterEntry());
347 
348     GRAPH(GetGraph())
349     {
350         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
351         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
352         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
353         INST(10U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
354 
355         BASIC_BLOCK(2U, -1L)
356         {
357             INST(8U, Opcode::LoadI).Inputs(2U).ptr().Imm(ManagedThread::GetFrameOffset());
358             INST(5U, Opcode::LoadI).Inputs(8U).Imm(frameAccOffset).ref();
359             INST(9U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
360 
361             // store tag
362             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
363             INST(31U, Opcode::StoreI).u64().Inputs(30U, 10U).Imm(accTagOffset);
364 
365             INST(3U, Opcode::Call).TypeId(0U).ptr();
366             INST(4U, Opcode::ReturnVoid).v0id();
367         }
368     }
369 
370     irtoc::IrtocRuntimeInterface runtime;
371     GetGraph()->SetRuntime(&runtime);
372 
373     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
374 }
375 
376 // Correct load accumulator from last frame definition with one instructions:
377 //    last_frame_def      := LoadI(LiveIn(frame).ptr).Imm(GetPrevFrameOffset()).ptr
378 //    correct_acc_load    := LoadI(last_frame_def).Imm(frame_acc_offset).ref
379 // Incorrect store into old frame with instruction:
380 //    incorrect_acc_store := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
TEST_F(DanglingPointersCheckerTest,test7)381 TEST_F(DanglingPointersCheckerTest, test7)
382 {
383     auto arch = panda::RUNTIME_ARCH;
384     SetGraphArch(arch);
385     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
386         return;
387     }
388     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
389     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
390     RelocationHandlerTest relocationHandler;
391     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
392     GetGraph()->SetRelocationHandler(&relocationHandler);
393     GetGraph()->SetMethod(&relocationHandler);
394     GetGraph()->SetMode(GraphMode::InterpreterEntry());
395 
396     GRAPH(GetGraph())
397     {
398         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
399         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
400         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
401         CONSTANT(10U, 10U).i64();
402         CONSTANT(11U, 15U).i64();
403 
404         BASIC_BLOCK(2U, -1L)
405         {
406             INST(8U, Opcode::LoadI).Inputs(0U).ptr().Imm(Frame::GetPrevFrameOffset());
407             INST(5U, Opcode::AddI).Inputs(8U).Imm(frameAccOffset).ptr();
408             INST(6U, Opcode::LoadI).Inputs(5U).ref().Imm(0U);
409             INST(7U, Opcode::Mul).Inputs(10U, 11U).i64();
410             INST(9U, Opcode::StoreI).ref().Inputs(0U, 6U).Imm(frameAccOffset);
411 
412             // store tag
413             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
414             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
415 
416             INST(3U, Opcode::Call).TypeId(0U).Inputs({{compiler::DataType::INT64, 7U}}).ptr();
417             INST(4U, Opcode::ReturnVoid).v0id();
418         }
419     }
420 
421     irtoc::IrtocRuntimeInterface runtime;
422     GetGraph()->SetRuntime(&runtime);
423 
424     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
425 }
426 
427 // Use old accumulator after Call
TEST_F(DanglingPointersCheckerTest,test8)428 TEST_F(DanglingPointersCheckerTest, test8)
429 {
430     auto arch = panda::RUNTIME_ARCH;
431     SetGraphArch(arch);
432     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
433         return;
434     }
435     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
436     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
437     RelocationHandlerTest relocationHandler;
438     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
439     GetGraph()->SetRelocationHandler(&relocationHandler);
440     GetGraph()->SetMethod(&relocationHandler);
441     GetGraph()->SetMode(GraphMode::InterpreterEntry());
442 
443     GRAPH(GetGraph())
444     {
445         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
446         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
447         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
448 
449         BASIC_BLOCK(2U, -1L)
450         {
451             INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
452             INST(6U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
453 
454             // store tag
455             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
456             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
457 
458             INST(3U, Opcode::Call).TypeId(0U).ptr();
459             INST(7U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
460             INST(4U, Opcode::ReturnVoid).v0id();
461         }
462     }
463 
464     irtoc::IrtocRuntimeInterface runtime;
465     GetGraph()->SetRuntime(&runtime);
466 
467     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
468 }
469 
470 // The correct graph. Not use old acc after call.
471 //          start_bb
472 //             |
473 //             V
474 //   ------------------------------------
475 //  | bb_2 | new_acc_load, new_acc_store |
476 //   ------------------------------------
477 //      |
478 //      V
479 //   --------------------    --------------------
480 //  | bb_3 | use_old_acc |  | bb_4 | use_old_acc |
481 //   --------------------    --------------------
482 //      |                      |
483 //      V                      V
484 //    -------------          ------
485 //   | bb_5 | Call |        | bb_8 |
486 //    -------------\        -------
487 //      |           |       A     |
488 //      V           V       |     V
489 //    ------         --------     ------
490 //   | bb_6 |       |  bb_7  |-->| bb_9 |--> end_bb
491 //    ------         --------     ------
492 
TEST_F(DanglingPointersCheckerTest,test9)493 TEST_F(DanglingPointersCheckerTest, test9)
494 {
495     auto arch = panda::RUNTIME_ARCH;
496     SetGraphArch(arch);
497     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
498         return;
499     }
500     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
501     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
502     RelocationHandlerTest relocationHandler;
503     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
504     GetGraph()->SetRelocationHandler(&relocationHandler);
505     GetGraph()->SetMethod(&relocationHandler);
506     GetGraph()->SetMode(GraphMode::InterpreterEntry());
507 
508     GRAPH(GetGraph())
509     {
510         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
511         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
512         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
513         CONSTANT(10U, 10U);
514         CONSTANT(11U, 11U);
515         CONSTANT(12U, 12U);
516 
517         BASIC_BLOCK(2U, 3U, 4U)
518         {
519             INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
520             INST(5U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
521             INST(19U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
522             INST(20U, Opcode::Mul).Inputs(12U, 19U).u64();
523             INST(22U, Opcode::If).Inputs(19U, 20U).b().CC(CC_LE);
524         }
525         BASIC_BLOCK(3U, 5U)
526         {
527             INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
528         }
529         BASIC_BLOCK(4U, 8U)
530         {
531             INST(7U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
532         }
533         BASIC_BLOCK(5U, 6U, 7U)
534         {
535             // store tag
536             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
537             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
538 
539             INST(3U, Opcode::Call).TypeId(0U).ptr();
540             INST(17U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
541             INST(18U, Opcode::Mul).Inputs(12U, 17U).u64();
542             INST(21U, Opcode::If).Inputs(17U, 18U).b().CC(CC_NE);
543         }
544         BASIC_BLOCK(6U, 9U)
545         {
546             INST(8U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
547         }
548         BASIC_BLOCK(7U, 8U, 9U)
549         {
550             INST(16U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
551             INST(9U, Opcode::Mul).Inputs(12U, 16U).u64();
552             INST(15U, Opcode::If).Inputs(9U, 16U).b().CC(CC_EQ);
553         }
554         BASIC_BLOCK(8U, 9U)
555         {
556             INST(13U, Opcode::AddI).Inputs(12U).Imm(frameAccOffset).u64();
557         }
558 
559         BASIC_BLOCK(9U, -1L)
560         {
561             INST(14U, Opcode::ReturnVoid).v0id();
562         }
563     }
564 
565     irtoc::IrtocRuntimeInterface runtime;
566     GetGraph()->SetRuntime(&runtime);
567 
568     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
569 }
570 
571 // The incorrect graph. Use old acc after call.
572 //          start_bb
573 //             |
574 //             V
575 //   ------------------------------------
576 //  | bb_2 | new_acc_load, new_acc_store |
577 //   ------------------------------------
578 //      |
579 //      V
580 //   --------------------    --------------------
581 //  | bb_3 | use_old_acc |  | bb_4 | use_old_acc |
582 //   --------------------    --------------------
583 //      |                      |
584 //      V                      V
585 //    -------------          --------------------
586 //   | bb_5 | Call |        | bb_8 | use_old_acc |
587 //    -------------\        ---------------------
588 //      |           |       A     |
589 //      V           V       |     V
590 //    ------         --------     ------
591 //   | bb_6 |       |  bb_7  |-->| bb_9 |--> end_bb
592 //    ------         --------     ------
593 
TEST_F(DanglingPointersCheckerTest,test10)594 TEST_F(DanglingPointersCheckerTest, test10)
595 {
596     auto arch = panda::RUNTIME_ARCH;
597     SetGraphArch(arch);
598     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
599         return;
600     }
601     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
602     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
603     RelocationHandlerTest relocationHandler;
604     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
605     GetGraph()->SetRelocationHandler(&relocationHandler);
606     GetGraph()->SetMethod(&relocationHandler);
607     GetGraph()->SetMode(GraphMode::InterpreterEntry());
608 
609     GRAPH(GetGraph())
610     {
611         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
612         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
613         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
614         CONSTANT(10U, 10U);
615         CONSTANT(11U, 11U);
616         CONSTANT(12U, 12U);
617 
618         BASIC_BLOCK(2U, 3U, 4U)
619         {
620             INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
621             INST(5U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
622             INST(19U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
623             INST(20U, Opcode::Mul).Inputs(12U, 19U).u64();
624             INST(22U, Opcode::If).Inputs(19U, 20U).b().CC(CC_LE);
625         }
626         BASIC_BLOCK(3U, 5U)
627         {
628             INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
629         }
630         BASIC_BLOCK(4U, 8U)
631         {
632             INST(7U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
633         }
634         BASIC_BLOCK(5U, 6U, 7U)
635         {
636             // store tag
637             INST(30U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
638             INST(31U, Opcode::StoreI).u64().Inputs(30U, 2U).Imm(accTagOffset);
639 
640             INST(3U, Opcode::Call).TypeId(0U).ptr();
641             INST(17U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
642             INST(18U, Opcode::Mul).Inputs(12U, 17U).u64();
643             INST(21U, Opcode::If).Inputs(17U, 18U).b().CC(CC_NE);
644         }
645         BASIC_BLOCK(6U, 9U)
646         {
647             INST(8U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
648         }
649         BASIC_BLOCK(7U, 8U, 9U)
650         {
651             INST(16U, Opcode::AddI).Inputs(11U).Imm(frameAccOffset).u64();
652             INST(9U, Opcode::Mul).Inputs(12U, 16U).u64();
653             INST(15U, Opcode::If).Inputs(9U, 16U).b().CC(CC_EQ);
654         }
655         BASIC_BLOCK(8U, 9U)
656         {
657             INST(23U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
658             INST(13U, Opcode::AddI).Inputs(12U).Imm(frameAccOffset).u64();
659         }
660 
661         BASIC_BLOCK(9U, -1L)
662         {
663             INST(14U, Opcode::ReturnVoid).v0id();
664         }
665     }
666 
667     irtoc::IrtocRuntimeInterface runtime;
668     GetGraph()->SetRuntime(&runtime);
669 
670     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
671 }
672 
673 // The correct graph. Use Phi to define acc that has been changed in one branch.
674 //          start_bb
675 //             |
676 //             V
677 //         -----------------------------
678 //        |           bb_2              |
679 //         -----------------------------
680 //         |                           |
681 //         V                           |
682 //   -----------------------------     |
683 //  | bb_3 | load_acc, change_acc |    |
684 //   -----------------------------     |
685 //                             |       |
686 //                             V       V
687 //               ------------------------------------------------
688 //              |      | last_acc_def = Phi(live_in, change_acc) |
689 //              | bb_4 | store(last_acc_def)                     |
690 //              |      | Call                                    |
691 //               ------------------------------------------------
692 //                                     |
693 //                                     V
694 //                                  end_bb
695 
TEST_F(DanglingPointersCheckerTest,test11)696 TEST_F(DanglingPointersCheckerTest, test11)
697 {
698     auto arch = panda::RUNTIME_ARCH;
699     SetGraphArch(arch);
700     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
701         return;
702     }
703     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
704     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
705     RelocationHandlerTest relocationHandler;
706     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
707     GetGraph()->SetRelocationHandler(&relocationHandler);
708     GetGraph()->SetMethod(&relocationHandler);
709     GetGraph()->SetMode(GraphMode::InterpreterEntry());
710 
711     GRAPH(GetGraph())
712     {
713         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
714         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
715         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
716         CONSTANT(10U, 10U);
717         CONSTANT(11U, 11U);
718 
719         BASIC_BLOCK(2U, 3U, 4U)
720         {
721             INST(3U, Opcode::AddI).Inputs(10U).Imm(frameAccOffset).u64();
722             INST(4U, Opcode::If).Inputs(3U, 11U).b().CC(CC_NE);
723         }
724         BASIC_BLOCK(3U, 4U)
725         {
726             INST(5U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
727             INST(6U, Opcode::AddI).Inputs(5U).ptr().Imm(10U);
728         }
729         BASIC_BLOCK(4U, -1L)
730         {
731             INST(7U, Opcode::Phi).Inputs(1U, 6U).ptr();
732             INST(8U, Opcode::StoreI).ref().Inputs(0U, 7U).Imm(frameAccOffset);
733 
734             // store tag
735             INST(21U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
736             INST(22U, Opcode::StoreI).u64().Inputs(21U, 2U).Imm(accTagOffset);
737 
738             INST(9U, Opcode::Call).TypeId(0U).ptr();
739             INST(20U, Opcode::ReturnVoid).v0id();
740         }
741     }
742 
743     irtoc::IrtocRuntimeInterface runtime;
744     GetGraph()->SetRuntime(&runtime);
745 
746     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
747 }
748 
749 // Use object after call:
750 //    frame_live_in := LiveIn(frame)
751 //    Call
752 //    frame_use := LoadI(frame_live_in).Imm(frame_acc_offset).i64
TEST_F(DanglingPointersCheckerTest,test12)753 TEST_F(DanglingPointersCheckerTest, test12)
754 {
755     auto arch = panda::RUNTIME_ARCH;
756     SetGraphArch(arch);
757     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
758         return;
759     }
760     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
761     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
762     RelocationHandlerTest relocationHandler;
763     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
764     GetGraph()->SetRelocationHandler(&relocationHandler);
765     GetGraph()->SetMethod(&relocationHandler);
766     GetGraph()->SetMode(GraphMode::InterpreterEntry());
767 
768     GRAPH(GetGraph())
769     {
770         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
771         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
772         INST(2U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
773 
774         BASIC_BLOCK(2U, -1L)
775         {
776             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
777 
778             // store tag
779             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
780             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
781 
782             INST(3U, Opcode::Call).TypeId(0U).ptr();
783             INST(5U, Opcode::AddI).Inputs(1U).ptr().Imm(frameAccOffset);
784             INST(4U, Opcode::ReturnVoid).v0id();
785         }
786     }
787 
788     irtoc::IrtocRuntimeInterface runtime;
789     GetGraph()->SetRuntime(&runtime);
790 
791     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
792 }
793 
794 // Use primitive after call:
795 //    frame_live_in := LiveIn(frame)
796 //    primitive := LoadI(frame_live_in).Imm(offset).u64
797 //    Call
798 //    primitive_use := AddI(not_object).Imm(10).u64
TEST_F(DanglingPointersCheckerTest,test13)799 TEST_F(DanglingPointersCheckerTest, test13)
800 {
801     auto arch = panda::RUNTIME_ARCH;
802     SetGraphArch(arch);
803     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
804         return;
805     }
806     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
807     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
808     RelocationHandlerTest relocationHandler;
809     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
810     GetGraph()->SetRelocationHandler(&relocationHandler);
811     GetGraph()->SetMethod(&relocationHandler);
812     GetGraph()->SetMode(GraphMode::InterpreterEntry());
813 
814     GRAPH(GetGraph())
815     {
816         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
817         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
818         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
819 
820         BASIC_BLOCK(2U, -1L)
821         {
822             INST(6U, Opcode::LoadI).Inputs(0U).u64().Imm(10U);
823             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
824 
825             // store tag
826             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
827             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
828 
829             INST(3U, Opcode::Call).TypeId(0U).ptr();
830             INST(5U, Opcode::AddI).Inputs(6U).u64().Imm(frameAccOffset);
831             INST(4U, Opcode::ReturnVoid).v0id();
832         }
833     }
834 
835     irtoc::IrtocRuntimeInterface runtime;
836     GetGraph()->SetRuntime(&runtime);
837 
838     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
839 }
840 
841 // Use skipped pointer inst after call:
842 //    frame_live_in := LiveIn(frame)
843 //    pointer := AddI(frame_live_in).Imm(frame_acc_offset).ptr
844 //    Call
845 //    primitive := LoadI(pointer).Imm(0).u64
TEST_F(DanglingPointersCheckerTest,test14)846 TEST_F(DanglingPointersCheckerTest, test14)
847 {
848     auto arch = panda::RUNTIME_ARCH;
849     SetGraphArch(arch);
850     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
851         return;
852     }
853     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
854     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
855     RelocationHandlerTest relocationHandler;
856     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
857     GetGraph()->SetRelocationHandler(&relocationHandler);
858     GetGraph()->SetMethod(&relocationHandler);
859     GetGraph()->SetMode(GraphMode::InterpreterEntry());
860 
861     GRAPH(GetGraph())
862     {
863         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
864         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
865         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
866 
867         BASIC_BLOCK(2U, -1L)
868         {
869             INST(6U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
870             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
871 
872             // store tag
873             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
874             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
875 
876             INST(3U, Opcode::Call).TypeId(0U).ptr();
877             INST(5U, Opcode::LoadI).Inputs(6U).u64().Imm(0U);
878             INST(4U, Opcode::ReturnVoid).v0id();
879         }
880     }
881 
882     irtoc::IrtocRuntimeInterface runtime;
883     GetGraph()->SetRuntime(&runtime);
884 
885     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
886 }
887 
888 // Use ref inst after call:
889 //    pointer := AddI(acc_live_in).Imm(10).ptr
890 //    Call
891 //    primitive := LoadI(pointer).Imm(0).u64
TEST_F(DanglingPointersCheckerTest,test15)892 TEST_F(DanglingPointersCheckerTest, test15)
893 {
894     auto arch = panda::RUNTIME_ARCH;
895     SetGraphArch(arch);
896     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
897         return;
898     }
899     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
900     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
901     RelocationHandlerTest relocationHandler;
902     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
903     GetGraph()->SetRelocationHandler(&relocationHandler);
904     GetGraph()->SetMethod(&relocationHandler);
905     GetGraph()->SetMode(GraphMode::InterpreterEntry());
906 
907     GRAPH(GetGraph())
908     {
909         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
910         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
911         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
912 
913         BASIC_BLOCK(2U, -1L)
914         {
915             INST(10U, Opcode::LoadI).Inputs(0U).ref().Imm(10U);
916             INST(6U, Opcode::AddI).Inputs(1U).ptr().Imm(10U);
917             INST(7U, Opcode::StoreI).ref().Inputs(0U, 1U).Imm(frameAccOffset);
918 
919             // store tag
920             INST(8U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
921             INST(9U, Opcode::StoreI).u64().Inputs(8U, 2U).Imm(accTagOffset);
922 
923             INST(3U, Opcode::Call).TypeId(0U).ptr();
924             INST(5U, Opcode::LoadI).Inputs(10U).u64().Imm(0U);
925             INST(4U, Opcode::ReturnVoid).v0id();
926         }
927     }
928 
929     irtoc::IrtocRuntimeInterface runtime;
930     GetGraph()->SetRuntime(&runtime);
931 
932     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
933 }
934 
935 // Correct load accumulator from frame:
936 //    correct_acc_load      := LoadI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
937 // Correct accumulatore and tag store:
938 //    correct_acc_store     := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
939 //    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
940 //    correct_acc_tag_store := StoreI(acc_ptr, LiveIn(acc_tag).u64).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test16)941 TEST_F(DanglingPointersCheckerTest, test16)
942 {
943     auto arch = panda::RUNTIME_ARCH;
944     SetGraphArch(arch);
945     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
946         return;
947     }
948     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
949     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
950     RelocationHandlerTest relocationHandler;
951     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
952     GetGraph()->SetRelocationHandler(&relocationHandler);
953     GetGraph()->SetMethod(&relocationHandler);
954     GetGraph()->SetMode(GraphMode::InterpreterEntry());
955 
956     GRAPH(GetGraph())
957     {
958         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
959         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
960         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
961         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
962 
963         BASIC_BLOCK(2U, -1L)
964         {
965             INST(4U, Opcode::LoadI).Inputs(0U).ref().Imm(frameAccOffset);
966             INST(5U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
967             INST(6U, Opcode::StoreI).ref().Inputs(0U, 4U).Imm(frameAccOffset);
968             INST(7U, Opcode::StoreI).u64().Inputs(5U, 2U).Imm(accTagOffset);
969             INST(8U, Opcode::Call).TypeId(0U).ptr();
970             INST(9U, Opcode::ReturnVoid).v0id();
971         }
972     }
973 
974     irtoc::IrtocRuntimeInterface runtime;
975     GetGraph()->SetRuntime(&runtime);
976 
977     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
978 }
979 
980 // Correct load accumulator and tag:
981 //    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
982 //    correct_acc_load      := LoadI(acc_ptr).Imm(frame_acc_offset).ref
983 //    correct_acc_tag_load  := LoadI(acc_ptr).Imm(acc_tag_offset).u64
984 // Correct accumulatore and tag store:
985 //    correct_acc_store     := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
986 //    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
987 //    correct_acc_tag_store := StoreI(acc_ptr, correct_acc_tag_load).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test17)988 TEST_F(DanglingPointersCheckerTest, test17)
989 {
990     auto arch = panda::RUNTIME_ARCH;
991     SetGraphArch(arch);
992     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
993         return;
994     }
995     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
996     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
997     RelocationHandlerTest relocationHandler;
998     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
999     GetGraph()->SetRelocationHandler(&relocationHandler);
1000     GetGraph()->SetMethod(&relocationHandler);
1001     GetGraph()->SetMode(GraphMode::InterpreterEntry());
1002 
1003     GRAPH(GetGraph())
1004     {
1005         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1006         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1007         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1008         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1009 
1010         BASIC_BLOCK(2U, -1L)
1011         {
1012             INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1013             INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1014             INST(6U, Opcode::LoadI).Inputs(4U).i64().Imm(accTagOffset);
1015             INST(7U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1016             INST(8U, Opcode::StoreI).u64().Inputs(4U, 6U).Imm(accTagOffset);
1017             INST(9U, Opcode::Call).TypeId(0U).ptr();
1018             INST(10U, Opcode::ReturnVoid).v0id();
1019         }
1020     }
1021 
1022     irtoc::IrtocRuntimeInterface runtime;
1023     GetGraph()->SetRuntime(&runtime);
1024 
1025     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
1026 }
1027 
1028 // Correct load accumulator and tag:
1029 //    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
1030 //    correct_acc_load      := LoadI(acc_ptr).Imm(frame_acc_offset).ref
1031 //    acc_tag_ptr           := AddI(acc_ptr).Imm(acc_tag_offset).ref
1032 //    correct_acc_tag_load  := LoadI(acc_tag_ptr).Imm(0).u64
1033 // Correct accumulatore and tag store:
1034 //    correct_acc_store     := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
1035 //    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
1036 //    correct_acc_tag_store := StoreI(acc_ptr, correct_acc_tag_load).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test18)1037 TEST_F(DanglingPointersCheckerTest, test18)
1038 {
1039     auto arch = panda::RUNTIME_ARCH;
1040     SetGraphArch(arch);
1041     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
1042         return;
1043     }
1044     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
1045     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
1046     RelocationHandlerTest relocationHandler;
1047     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
1048     GetGraph()->SetRelocationHandler(&relocationHandler);
1049     GetGraph()->SetMethod(&relocationHandler);
1050     GetGraph()->SetMode(GraphMode::InterpreterEntry());
1051 
1052     GRAPH(GetGraph())
1053     {
1054         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1055         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1056         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1057         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1058 
1059         BASIC_BLOCK(2U, -1L)
1060         {
1061             INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1062             INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1063             INST(6U, Opcode::AddI).Inputs(4U).ptr().Imm(accTagOffset);
1064             INST(7U, Opcode::LoadI).Inputs(6U).i64().Imm(0U);
1065             INST(8U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1066             INST(9U, Opcode::StoreI).u64().Inputs(4U, 7U).Imm(accTagOffset);
1067             INST(10U, Opcode::Call).TypeId(0U).ptr();
1068             INST(11U, Opcode::ReturnVoid).v0id();
1069         }
1070     }
1071 
1072     irtoc::IrtocRuntimeInterface runtime;
1073     GetGraph()->SetRuntime(&runtime);
1074 
1075     ASSERT_TRUE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
1076 }
1077 
1078 // Correct load accumulator and tag:
1079 //    acc_ptr               := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ptr
1080 //    correct_acc_load      := LoadI(acc_ptr).Imm(frame_acc_offset).ref
1081 //    acc_tag_ptr           := AddI(acc_ptr).Imm(acc_tag_offset).ref
1082 //    correct_acc_tag_load  := LoadI(acc_tag_ptr).Imm(0).u64
1083 // Correct accumulatore and tag store:
1084 //    correct_acc_store       := StoreI(LiveIn(frame).ptr, correct_acc_load).Imm(frame_acc_offset).ref
1085 //    acc_ptr                 := AddI(LiveIn(frame).ptr).Imm(frame_acc_offset).ref
1086 //    incorrect_acc_tag_store := StoreI(acc_ptr, LiveIn(acc_tag).u64).Imm(acc_tag_offset).u64
TEST_F(DanglingPointersCheckerTest,test19)1087 TEST_F(DanglingPointersCheckerTest, test19)
1088 {
1089     auto arch = panda::RUNTIME_ARCH;
1090     SetGraphArch(arch);
1091     if (DanglingPointersChecker::regmap_.find(arch) == DanglingPointersChecker::regmap_.end()) {
1092         return;
1093     }
1094     auto frameAccOffset = cross_values::GetFrameAccOffset(arch);
1095     auto accTagOffset = cross_values::GetFrameAccMirrorOffset(arch);
1096     RelocationHandlerTest relocationHandler;
1097     relocationHandler.SetTestExternalFunctions({*DanglingPointersChecker::targetFuncs_.begin()});
1098     GetGraph()->SetRelocationHandler(&relocationHandler);
1099     GetGraph()->SetMethod(&relocationHandler);
1100     GetGraph()->SetMode(GraphMode::InterpreterEntry());
1101 
1102     GRAPH(GetGraph())
1103     {
1104         INST(0U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["frame"]);
1105         INST(1U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["acc"]);
1106         INST(2U, Opcode::LiveIn).u64().DstReg(DanglingPointersChecker::regmap_[arch]["acc_tag"]);
1107         INST(3U, Opcode::LiveIn).ptr().DstReg(DanglingPointersChecker::regmap_[arch]["thread"]);
1108 
1109         BASIC_BLOCK(2U, -1L)
1110         {
1111             INST(4U, Opcode::AddI).Inputs(0U).ptr().Imm(frameAccOffset);
1112             INST(5U, Opcode::LoadI).Inputs(4U).ref().Imm(0U);
1113             INST(6U, Opcode::AddI).Inputs(4U).ptr().Imm(accTagOffset);
1114             INST(7U, Opcode::LoadI).Inputs(6U).i64().Imm(0U);
1115             INST(8U, Opcode::StoreI).ref().Inputs(0U, 5U).Imm(frameAccOffset);
1116             INST(9U, Opcode::StoreI).u64().Inputs(4U, 2U).Imm(accTagOffset);
1117             INST(10U, Opcode::Call).TypeId(0U).ptr();
1118             INST(11U, Opcode::ReturnVoid).v0id();
1119         }
1120     }
1121 
1122     irtoc::IrtocRuntimeInterface runtime;
1123     GetGraph()->SetRuntime(&runtime);
1124 
1125     ASSERT_FALSE(GetGraph()->RunPass<panda::compiler::DanglingPointersChecker>());
1126 }
1127 
1128 // NOLINTEND(readability-magic-numbers)
1129 }  // namespace panda::compiler
1130