File: | unittests/ExecutionEngine/MCJIT/MCJITTest.cpp |
Location: | line 58, column 3 |
Description: | Forming reference to null pointer |
1 | //===- MCJITTest.cpp - Unit tests for the MCJIT -----------------*- C++ -*-===// | |||||
2 | // | |||||
3 | // The LLVM Compiler Infrastructure | |||||
4 | // | |||||
5 | // This file is distributed under the University of Illinois Open Source | |||||
6 | // License. See LICENSE.TXT for details. | |||||
7 | // | |||||
8 | //===----------------------------------------------------------------------===// | |||||
9 | // | |||||
10 | // This test suite verifies basic MCJIT functionality such as making function | |||||
11 | // calls, using global variables, and compiling multpile modules. | |||||
12 | // | |||||
13 | //===----------------------------------------------------------------------===// | |||||
14 | ||||||
15 | #include "llvm/ExecutionEngine/MCJIT.h" | |||||
16 | #include "llvm/Support/DynamicLibrary.h" | |||||
17 | #include "MCJITTestBase.h" | |||||
18 | #include "gtest/gtest.h" | |||||
19 | ||||||
20 | using namespace llvm; | |||||
21 | ||||||
22 | namespace { | |||||
23 | ||||||
24 | class MCJITTest : public testing::Test, public MCJITTestBase { | |||||
25 | protected: | |||||
26 | void SetUp() override { M.reset(createEmptyModule("<main>")); } | |||||
27 | }; | |||||
28 | ||||||
29 | // FIXME: Ensure creating an execution engine does not crash when constructed | |||||
30 | // with a null module. | |||||
31 | /* | |||||
32 | TEST_F(MCJITTest, null_module) { | |||||
33 | createJIT(0); | |||||
34 | } | |||||
35 | */ | |||||
36 | ||||||
37 | // FIXME: In order to JIT an empty module, there needs to be | |||||
38 | // an interface to ExecutionEngine that forces compilation but | |||||
39 | // does not require retrieval of a pointer to a function/global. | |||||
40 | /* | |||||
41 | TEST_F(MCJITTest, empty_module) { | |||||
42 | createJIT(M.take()); | |||||
43 | //EXPECT_NE(0, TheJIT->getObjectImage()) | |||||
44 | // << "Unable to generate executable loaded object image"; | |||||
45 | } | |||||
46 | */ | |||||
47 | ||||||
48 | TEST_F(MCJITTest, global_variable)class MCJITTest_global_variable_Test : public MCJITTest { public : MCJITTest_global_variable_Test() {} private: virtual void TestBody (); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); MCJITTest_global_variable_Test(MCJITTest_global_variable_Test const &); void operator=(MCJITTest_global_variable_Test const &);};::testing::TestInfo* const MCJITTest_global_variable_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "global_variable", __null, __null, (::testing:: internal::GetTypeId<MCJITTest>()), MCJITTest::SetUpTestCase , MCJITTest::TearDownTestCase, new ::testing::internal::TestFactoryImpl < MCJITTest_global_variable_Test>);void MCJITTest_global_variable_Test ::TestBody() { | |||||
49 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
50 | ||||||
51 | int initialValue = 5; | |||||
52 | GlobalValue *Global = insertGlobalInt32(M.get(), "test_global", initialValue); | |||||
53 | createJIT(std::move(M)); | |||||
54 | void *globalPtr = TheJIT->getPointerToGlobal(Global); | |||||
| ||||||
55 | EXPECT_TRUE(nullptr != globalPtr)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(nullptr != globalPtr) ) ; else ::testing::internal::AssertHelper(::testing::TestPartResult ::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 55, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "nullptr != globalPtr", "false", "true").c_str()) = ::testing ::Message() | |||||
56 | << "Unable to get pointer to global value from JIT"; | |||||
57 | ||||||
58 | EXPECT_EQ(initialValue, *(int32_t*)globalPtr)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(initialValue)) == 1)>::Compare ("initialValue", "*(int32_t*)globalPtr", initialValue, *(int32_t *)globalPtr))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 58, gtest_ar.failure_message()) = ::testing::Message() | |||||
| ||||||
59 | << "Unexpected initial value of global"; | |||||
60 | } | |||||
61 | ||||||
62 | TEST_F(MCJITTest, add_function)class MCJITTest_add_function_Test : public MCJITTest { public : MCJITTest_add_function_Test() {} private: virtual void TestBody (); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); MCJITTest_add_function_Test(MCJITTest_add_function_Test const &); void operator=(MCJITTest_add_function_Test const &);};::testing::TestInfo* const MCJITTest_add_function_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "add_function", __null, __null, (::testing::internal ::GetTypeId<MCJITTest>()), MCJITTest::SetUpTestCase, MCJITTest ::TearDownTestCase, new ::testing::internal::TestFactoryImpl< MCJITTest_add_function_Test>);void MCJITTest_add_function_Test ::TestBody() { | |||||
63 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
64 | ||||||
65 | Function *F = insertAddFunction(M.get()); | |||||
66 | createJIT(std::move(M)); | |||||
67 | uint64_t addPtr = TheJIT->getFunctionAddress(F->getName().str()); | |||||
68 | EXPECT_TRUE(0 != addPtr)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(0 != addPtr)) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 68, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "0 != addPtr", "false", "true").c_str()) = ::testing::Message () | |||||
69 | << "Unable to get pointer to function from JIT"; | |||||
70 | ||||||
71 | ASSERT_TRUE(addPtr != 0)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(addPtr != 0)) ; else return ::testing::internal::AssertHelper(::testing::TestPartResult:: kFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 71, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "addPtr != 0", "false", "true").c_str()) = ::testing::Message () << "Unable to get pointer to function ."; | |||||
72 | int (*AddPtr)(int, int) = (int(*)(int, int))addPtr ; | |||||
73 | EXPECT_EQ(0, AddPtr(0, 0))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(0)) == 1)>::Compare("0", "AddPtr(0, 0)" , 0, AddPtr(0, 0)))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 73, gtest_ar.failure_message()) = ::testing::Message(); | |||||
74 | EXPECT_EQ(1, AddPtr(1, 0))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(1)) == 1)>::Compare("1", "AddPtr(1, 0)" , 1, AddPtr(1, 0)))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 74, gtest_ar.failure_message()) = ::testing::Message(); | |||||
75 | EXPECT_EQ(3, AddPtr(1, 2))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(3)) == 1)>::Compare("3", "AddPtr(1, 2)" , 3, AddPtr(1, 2)))) ; else ::testing::internal::AssertHelper (::testing::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 75, gtest_ar.failure_message()) = ::testing::Message(); | |||||
76 | EXPECT_EQ(-5, AddPtr(-2, -3))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(-5)) == 1)>::Compare("-5", "AddPtr(-2, -3)", -5, AddPtr(-2, -3)))) ; else ::testing::internal ::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 76, gtest_ar.failure_message()) = ::testing::Message(); | |||||
77 | EXPECT_EQ(30, AddPtr(10, 20))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(30)) == 1)>::Compare("30", "AddPtr(10, 20)", 30, AddPtr(10, 20)))) ; else ::testing::internal ::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 77, gtest_ar.failure_message()) = ::testing::Message(); | |||||
78 | EXPECT_EQ(-30, AddPtr(-10, -20))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(-30)) == 1)>::Compare("-30" , "AddPtr(-10, -20)", -30, AddPtr(-10, -20)))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 78, gtest_ar.failure_message()) = ::testing::Message(); | |||||
79 | EXPECT_EQ(-40, AddPtr(-10, -30))switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(-40)) == 1)>::Compare("-40" , "AddPtr(-10, -30)", -40, AddPtr(-10, -30)))) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 79, gtest_ar.failure_message()) = ::testing::Message(); | |||||
80 | } | |||||
81 | ||||||
82 | TEST_F(MCJITTest, run_main)class MCJITTest_run_main_Test : public MCJITTest { public: MCJITTest_run_main_Test () {} private: virtual void TestBody(); static ::testing::TestInfo * const test_info_ __attribute__ ((unused)); MCJITTest_run_main_Test (MCJITTest_run_main_Test const &); void operator=(MCJITTest_run_main_Test const &);};::testing::TestInfo* const MCJITTest_run_main_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "run_main", __null, __null, (::testing::internal ::GetTypeId<MCJITTest>()), MCJITTest::SetUpTestCase, MCJITTest ::TearDownTestCase, new ::testing::internal::TestFactoryImpl< MCJITTest_run_main_Test>);void MCJITTest_run_main_Test::TestBody () { | |||||
83 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
84 | ||||||
85 | int rc = 6; | |||||
86 | Function *Main = insertMainFunction(M.get(), 6); | |||||
87 | createJIT(std::move(M)); | |||||
88 | uint64_t ptr = TheJIT->getFunctionAddress(Main->getName().str()); | |||||
89 | EXPECT_TRUE(0 != ptr)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(0 != ptr)) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 89, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "0 != ptr", "false", "true").c_str()) = ::testing::Message( ) | |||||
90 | << "Unable to get pointer to main() from JIT"; | |||||
91 | ||||||
92 | int (*FuncPtr)() = (int(*)())ptr; | |||||
93 | int returnCode = FuncPtr(); | |||||
94 | EXPECT_EQ(returnCode, rc)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(returnCode)) == 1)>::Compare ("returnCode", "rc", returnCode, rc))) ; else ::testing::internal ::AssertHelper(::testing::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 94, gtest_ar.failure_message()) = ::testing::Message(); | |||||
95 | } | |||||
96 | ||||||
97 | TEST_F(MCJITTest, return_global)class MCJITTest_return_global_Test : public MCJITTest { public : MCJITTest_return_global_Test() {} private: virtual void TestBody (); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); MCJITTest_return_global_Test(MCJITTest_return_global_Test const &); void operator=(MCJITTest_return_global_Test const &);};::testing::TestInfo* const MCJITTest_return_global_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "return_global", __null, __null, (::testing::internal ::GetTypeId<MCJITTest>()), MCJITTest::SetUpTestCase, MCJITTest ::TearDownTestCase, new ::testing::internal::TestFactoryImpl< MCJITTest_return_global_Test>);void MCJITTest_return_global_Test ::TestBody() { | |||||
98 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
99 | ||||||
100 | int32_t initialNum = 7; | |||||
101 | GlobalVariable *GV = insertGlobalInt32(M.get(), "myglob", initialNum); | |||||
102 | ||||||
103 | Function *ReturnGlobal = startFunction<int32_t(void)>(M.get(), | |||||
104 | "ReturnGlobal"); | |||||
105 | Value *ReadGlobal = Builder.CreateLoad(GV); | |||||
106 | endFunctionWithRet(ReturnGlobal, ReadGlobal); | |||||
107 | ||||||
108 | createJIT(std::move(M)); | |||||
109 | uint64_t rgvPtr = TheJIT->getFunctionAddress(ReturnGlobal->getName().str()); | |||||
110 | EXPECT_TRUE(0 != rgvPtr)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(0 != rgvPtr)) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 110, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "0 != rgvPtr", "false", "true").c_str()) = ::testing::Message (); | |||||
111 | ||||||
112 | int32_t(*FuncPtr)() = (int32_t(*)())rgvPtr; | |||||
113 | EXPECT_EQ(initialNum, FuncPtr())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(initialNum)) == 1)>::Compare ("initialNum", "FuncPtr()", initialNum, FuncPtr()))) ; else :: testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 113, gtest_ar.failure_message()) = ::testing::Message() | |||||
114 | << "Invalid value for global returned from JITted function"; | |||||
115 | } | |||||
116 | ||||||
117 | // FIXME: This case fails due to a bug with getPointerToGlobal(). | |||||
118 | // The bug is due to MCJIT not having an implementation of getPointerToGlobal() | |||||
119 | // which results in falling back on the ExecutionEngine implementation that | |||||
120 | // allocates a new memory block for the global instead of using the same | |||||
121 | // global variable that is emitted by MCJIT. Hence, the pointer (gvPtr below) | |||||
122 | // has the correct initial value, but updates to the real global (accessed by | |||||
123 | // JITted code) are not propagated. Instead, getPointerToGlobal() should return | |||||
124 | // a pointer into the loaded ObjectImage to reference the emitted global. | |||||
125 | /* | |||||
126 | TEST_F(MCJITTest, increment_global) { | |||||
127 | SKIP_UNSUPPORTED_PLATFORM; | |||||
128 | ||||||
129 | int32_t initialNum = 5; | |||||
130 | Function *IncrementGlobal = startFunction<int32_t(void)>(M.get(), "IncrementGlobal"); | |||||
131 | GlobalVariable *GV = insertGlobalInt32(M.get(), "my_global", initialNum); | |||||
132 | Value *DerefGV = Builder.CreateLoad(GV); | |||||
133 | Value *AddResult = Builder.CreateAdd(DerefGV, | |||||
134 | ConstantInt::get(Context, APInt(32, 1))); | |||||
135 | Builder.CreateStore(AddResult, GV); | |||||
136 | endFunctionWithRet(IncrementGlobal, AddResult); | |||||
137 | ||||||
138 | createJIT(M.take()); | |||||
139 | void *gvPtr = TheJIT->getPointerToGlobal(GV); | |||||
140 | EXPECT_EQ(initialNum, *(int32_t*)gvPtr); | |||||
141 | ||||||
142 | void *vPtr = TheJIT->getFunctionAddress(IncrementGlobal->getName().str()); | |||||
143 | EXPECT_TRUE(0 != vPtr) | |||||
144 | << "Unable to get pointer to main() from JIT"; | |||||
145 | ||||||
146 | int32_t(*FuncPtr)(void) = (int32_t(*)(void))(intptr_t)vPtr; | |||||
147 | ||||||
148 | for(int i = 1; i < 3; ++i) { | |||||
149 | int32_t result = FuncPtr(); | |||||
150 | EXPECT_EQ(initialNum + i, result); // OK | |||||
151 | EXPECT_EQ(initialNum + i, *(int32_t*)gvPtr); // FAILS | |||||
152 | } | |||||
153 | } | |||||
154 | */ | |||||
155 | ||||||
156 | // PR16013: XFAIL this test on ARM, which currently can't handle multiple relocations. | |||||
157 | #if !defined(__arm__) | |||||
158 | ||||||
159 | TEST_F(MCJITTest, multiple_functions)class MCJITTest_multiple_functions_Test : public MCJITTest { public : MCJITTest_multiple_functions_Test() {} private: virtual void TestBody(); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); MCJITTest_multiple_functions_Test(MCJITTest_multiple_functions_Test const &); void operator=(MCJITTest_multiple_functions_Test const &);};::testing::TestInfo* const MCJITTest_multiple_functions_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "multiple_functions", __null, __null, (::testing ::internal::GetTypeId<MCJITTest>()), MCJITTest::SetUpTestCase , MCJITTest::TearDownTestCase, new ::testing::internal::TestFactoryImpl < MCJITTest_multiple_functions_Test>);void MCJITTest_multiple_functions_Test ::TestBody() { | |||||
160 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
161 | ||||||
162 | unsigned int numLevels = 23; | |||||
163 | int32_t innerRetVal= 5; | |||||
164 | ||||||
165 | Function *Inner = startFunction<int32_t(void)>(M.get(), "Inner"); | |||||
166 | endFunctionWithRet(Inner, ConstantInt::get(Context, APInt(32, innerRetVal))); | |||||
167 | ||||||
168 | Function *Outer; | |||||
169 | for (unsigned int i = 0; i < numLevels; ++i) { | |||||
170 | std::stringstream funcName; | |||||
171 | funcName << "level_" << i; | |||||
172 | Outer = startFunction<int32_t(void)>(M.get(), funcName.str()); | |||||
173 | Value *innerResult = Builder.CreateCall(Inner, {}); | |||||
174 | endFunctionWithRet(Outer, innerResult); | |||||
175 | ||||||
176 | Inner = Outer; | |||||
177 | } | |||||
178 | ||||||
179 | createJIT(std::move(M)); | |||||
180 | uint64_t ptr = TheJIT->getFunctionAddress(Outer->getName().str()); | |||||
181 | EXPECT_TRUE(0 != ptr)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(0 != ptr)) ; else ::testing ::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure , "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 181, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "0 != ptr", "false", "true").c_str()) = ::testing::Message( ) | |||||
182 | << "Unable to get pointer to outer function from JIT"; | |||||
183 | ||||||
184 | int32_t(*FuncPtr)() = (int32_t(*)())ptr; | |||||
185 | EXPECT_EQ(innerRetVal, FuncPtr())switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(innerRetVal)) == 1)>::Compare ("innerRetVal", "FuncPtr()", innerRetVal, FuncPtr()))) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 185, gtest_ar.failure_message()) = ::testing::Message() | |||||
186 | << "Incorrect result returned from function"; | |||||
187 | } | |||||
188 | ||||||
189 | #endif /*!defined(__arm__)*/ | |||||
190 | ||||||
191 | TEST_F(MCJITTest, multiple_decl_lookups)class MCJITTest_multiple_decl_lookups_Test : public MCJITTest { public: MCJITTest_multiple_decl_lookups_Test() {} private: virtual void TestBody(); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); MCJITTest_multiple_decl_lookups_Test (MCJITTest_multiple_decl_lookups_Test const &); void operator =(MCJITTest_multiple_decl_lookups_Test const &);};::testing ::TestInfo* const MCJITTest_multiple_decl_lookups_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "multiple_decl_lookups", __null, __null, (::testing::internal ::GetTypeId<MCJITTest>()), MCJITTest::SetUpTestCase, MCJITTest ::TearDownTestCase, new ::testing::internal::TestFactoryImpl< MCJITTest_multiple_decl_lookups_Test>);void MCJITTest_multiple_decl_lookups_Test ::TestBody() { | |||||
192 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
193 | ||||||
194 | Function *Foo = insertExternalReferenceToFunction<void(void)>(M.get(), "_exit"); | |||||
195 | createJIT(std::move(M)); | |||||
196 | void *A = TheJIT->getPointerToFunction(Foo); | |||||
197 | void *B = TheJIT->getPointerToFunction(Foo); | |||||
198 | ||||||
199 | EXPECT_TRUE(A != nullptr)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(A != nullptr)) ; else ::testing::internal::AssertHelper(::testing::TestPartResult:: kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 199, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "A != nullptr", "false", "true").c_str()) = ::testing::Message () << "Failed lookup - test not correctly configured."; | |||||
200 | EXPECT_EQ(A, B)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(A)) == 1)>::Compare("A", "B" , A, B))) ; else ::testing::internal::AssertHelper(::testing:: TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 200, gtest_ar.failure_message()) = ::testing::Message() << "Repeat calls to getPointerToFunction fail."; | |||||
201 | } | |||||
202 | ||||||
203 | typedef void * (*FunctionHandlerPtr)(const std::string &str); | |||||
204 | ||||||
205 | TEST_F(MCJITTest, lazy_function_creator_pointer)class MCJITTest_lazy_function_creator_pointer_Test : public MCJITTest { public: MCJITTest_lazy_function_creator_pointer_Test() {} private : virtual void TestBody(); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); MCJITTest_lazy_function_creator_pointer_Test (MCJITTest_lazy_function_creator_pointer_Test const &); void operator=(MCJITTest_lazy_function_creator_pointer_Test const &);};::testing::TestInfo* const MCJITTest_lazy_function_creator_pointer_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "lazy_function_creator_pointer", __null, __null , (::testing::internal::GetTypeId<MCJITTest>()), MCJITTest ::SetUpTestCase, MCJITTest::TearDownTestCase, new ::testing:: internal::TestFactoryImpl< MCJITTest_lazy_function_creator_pointer_Test >);void MCJITTest_lazy_function_creator_pointer_Test::TestBody () { | |||||
206 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
207 | ||||||
208 | Function *Foo = insertExternalReferenceToFunction<int32_t(void)>(M.get(), | |||||
209 | "\1Foo"); | |||||
210 | startFunction<int32_t(void)>(M.get(), "Parent"); | |||||
211 | CallInst *Call = Builder.CreateCall(Foo, {}); | |||||
212 | Builder.CreateRet(Call); | |||||
213 | ||||||
214 | createJIT(std::move(M)); | |||||
215 | ||||||
216 | // Set up the lazy function creator that records the name of the last | |||||
217 | // unresolved external function found in the module. Using a function pointer | |||||
218 | // prevents us from capturing local variables, which is why this is static. | |||||
219 | static std::string UnresolvedExternal; | |||||
220 | FunctionHandlerPtr UnresolvedHandler = [] (const std::string &str) { | |||||
221 | // Try to resolve the function in the current process before marking it as | |||||
222 | // unresolved. This solves an issue on ARM where '__aeabi_*' function names | |||||
223 | // are passed to this handler. | |||||
224 | void *symbol = | |||||
225 | llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(str.c_str()); | |||||
226 | if (symbol) { | |||||
227 | return symbol; | |||||
228 | } | |||||
229 | ||||||
230 | UnresolvedExternal = str; | |||||
231 | return (void *)(uintptr_t)-1; | |||||
232 | }; | |||||
233 | TheJIT->InstallLazyFunctionCreator(UnresolvedHandler); | |||||
234 | ||||||
235 | // JIT the module. | |||||
236 | TheJIT->finalizeObject(); | |||||
237 | ||||||
238 | // Verify that our handler was called. | |||||
239 | EXPECT_EQ(UnresolvedExternal, "Foo")switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(UnresolvedExternal)) == 1)> ::Compare("UnresolvedExternal", "\"Foo\"", UnresolvedExternal , "Foo"))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 239, gtest_ar.failure_message()) = ::testing::Message(); | |||||
240 | } | |||||
241 | ||||||
242 | TEST_F(MCJITTest, lazy_function_creator_lambda)class MCJITTest_lazy_function_creator_lambda_Test : public MCJITTest { public: MCJITTest_lazy_function_creator_lambda_Test() {} private : virtual void TestBody(); static ::testing::TestInfo* const test_info_ __attribute__ ((unused)); MCJITTest_lazy_function_creator_lambda_Test (MCJITTest_lazy_function_creator_lambda_Test const &); void operator=(MCJITTest_lazy_function_creator_lambda_Test const & );};::testing::TestInfo* const MCJITTest_lazy_function_creator_lambda_Test ::test_info_ = ::testing::internal::MakeAndRegisterTestInfo( "MCJITTest", "lazy_function_creator_lambda", __null, __null, (::testing::internal::GetTypeId<MCJITTest>()), MCJITTest ::SetUpTestCase, MCJITTest::TearDownTestCase, new ::testing:: internal::TestFactoryImpl< MCJITTest_lazy_function_creator_lambda_Test >);void MCJITTest_lazy_function_creator_lambda_Test::TestBody () { | |||||
243 | SKIP_UNSUPPORTED_PLATFORMdo if (!ArchSupportsMCJIT() || !OSSupportsMCJIT()) return; while (0); | |||||
244 | ||||||
245 | Function *Foo1 = insertExternalReferenceToFunction<int32_t(void)>(M.get(), | |||||
246 | "\1Foo1"); | |||||
247 | Function *Foo2 = insertExternalReferenceToFunction<int32_t(void)>(M.get(), | |||||
248 | "\1Foo2"); | |||||
249 | startFunction<int32_t(void)>(M.get(), "Parent"); | |||||
250 | CallInst *Call1 = Builder.CreateCall(Foo1, {}); | |||||
251 | CallInst *Call2 = Builder.CreateCall(Foo2, {}); | |||||
252 | Value *Result = Builder.CreateAdd(Call1, Call2); | |||||
253 | Builder.CreateRet(Result); | |||||
254 | ||||||
255 | createJIT(std::move(M)); | |||||
256 | ||||||
257 | // Set up the lazy function creator that records the name of unresolved | |||||
258 | // external functions in the module. | |||||
259 | std::vector<std::string> UnresolvedExternals; | |||||
260 | auto UnresolvedHandler = [&UnresolvedExternals] (const std::string &str) { | |||||
261 | // Try to resolve the function in the current process before marking it as | |||||
262 | // unresolved. This solves an issue on ARM where '__aeabi_*' function names | |||||
263 | // are passed to this handler. | |||||
264 | void *symbol = | |||||
265 | llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(str.c_str()); | |||||
266 | if (symbol) { | |||||
267 | return symbol; | |||||
268 | } | |||||
269 | UnresolvedExternals.push_back(str); | |||||
270 | return (void *)(uintptr_t)-1; | |||||
271 | }; | |||||
272 | TheJIT->InstallLazyFunctionCreator(UnresolvedHandler); | |||||
273 | ||||||
274 | // JIT the module. | |||||
275 | TheJIT->finalizeObject(); | |||||
276 | ||||||
277 | // Verify that our handler was called for each unresolved function. | |||||
278 | auto I = UnresolvedExternals.begin(), E = UnresolvedExternals.end(); | |||||
279 | EXPECT_EQ(UnresolvedExternals.size(), 2u)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar = (::testing::internal:: EqHelper<(sizeof(::testing ::internal::IsNullLiteralHelper(UnresolvedExternals.size())) == 1)>::Compare("UnresolvedExternals.size()", "2u", UnresolvedExternals .size(), 2u))) ; else ::testing::internal::AssertHelper(::testing ::TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 279, gtest_ar.failure_message()) = ::testing::Message(); | |||||
280 | EXPECT_FALSE(std::find(I, E, "Foo1") == E)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(std::find(I, E, "Foo1" ) == E))) ; else ::testing::internal::AssertHelper(::testing:: TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 280, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "std::find(I, E, \"Foo1\") == E", "true", "false").c_str()) = ::testing::Message(); | |||||
281 | EXPECT_FALSE(std::find(I, E, "Foo2") == E)switch (0) case 0: default: if (const ::testing::AssertionResult gtest_ar_ = ::testing::AssertionResult(!(std::find(I, E, "Foo2" ) == E))) ; else ::testing::internal::AssertHelper(::testing:: TestPartResult::kNonFatalFailure, "/tmp/buildd/llvm-toolchain-snapshot-3.8~svn257205/unittests/ExecutionEngine/MCJIT/MCJITTest.cpp" , 281, ::testing::internal::GetBoolAssertionFailureMessage( gtest_ar_ , "std::find(I, E, \"Foo2\") == E", "true", "false").c_str()) = ::testing::Message(); | |||||
282 | } | |||||
283 | ||||||
284 | } // end anonymous namespace |