@@ -1491,6 +1491,91 @@ TEST(FunctionReflectionTest, JitCallAdvanced) {
14911491 clang_Interpreter_dispose (I);
14921492}
14931493
1494+ #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
1495+ #ifndef _WIN32 // Death tests do not work on Windows
1496+ TEST (FunctionReflectionTest, JitCallDebug) {
1497+ #ifdef EMSCRIPTEN
1498+ #if CLANG_VERSION_MAJOR < 20
1499+ GTEST_SKIP () << " Test fails for Emscipten builds" ;
1500+ #endif
1501+ #endif
1502+ if (llvm::sys::RunningOnValgrind ())
1503+ GTEST_SKIP () << " XFAIL due to Valgrind report" ;
1504+
1505+ std::vector<Decl*> Decls, SubDecls;
1506+ std::string code = R"(
1507+ class C {
1508+ int x;
1509+ C() {
1510+ x = 12345;
1511+ }
1512+ };)" ;
1513+
1514+ std::vector<const char *> interpreter_args = {" -include" , " new" ,
1515+ " -debug-only=jitcall" };
1516+ GetAllTopLevelDecls (code, Decls, /* filter_implicitGenerated=*/ false ,
1517+ interpreter_args);
1518+
1519+ const auto * CtorD = Cpp::GetDefaultConstructor (Decls[0 ]);
1520+ auto JC = Cpp::MakeFunctionCallable (CtorD);
1521+
1522+ EXPECT_TRUE (JC.getKind () == Cpp::JitCall::kConstructorCall );
1523+ EXPECT_DEATH (
1524+ { JC.InvokeConstructor (/* result=*/ nullptr ); },
1525+ " Must pass the location of the created object!" );
1526+
1527+ void * result = Cpp::Allocate (Decls[0 ]);
1528+ EXPECT_DEATH (
1529+ { JC.InvokeConstructor (&result, 0UL ); },
1530+ " Number of objects to construct should be atleast 1" );
1531+
1532+ // Succeeds
1533+ JC.InvokeConstructor (&result, 5UL );
1534+
1535+ Decls.clear ();
1536+ code = R"(
1537+ class C {
1538+ public:
1539+ int x;
1540+ C(int a) {
1541+ x = a;
1542+ }
1543+ ~C() {}
1544+ };)" ;
1545+
1546+ GetAllTopLevelDecls (code, Decls, /* filter_implicitGenerated=*/ false ,
1547+ interpreter_args);
1548+ GetAllSubDecls (Decls[0 ], SubDecls);
1549+
1550+ EXPECT_TRUE (Cpp::IsConstructor (SubDecls[3 ]));
1551+ JC = Cpp::MakeFunctionCallable (SubDecls[3 ]);
1552+ EXPECT_TRUE (JC.getKind () == Cpp::JitCall::kConstructorCall );
1553+
1554+ result = Cpp::Allocate (Decls[0 ], 5 );
1555+ int i = 42 ;
1556+ void * args0[1 ] = {(void *)&i};
1557+ EXPECT_DEATH (
1558+ { JC.InvokeConstructor (&result, 5UL , {args0, 1 }); },
1559+ " Cannot pass initialization parameters to array new construction" );
1560+
1561+ JC.InvokeConstructor (&result, 1UL , {args0, 1 }, (void *)~0 );
1562+
1563+ int * obj = reinterpret_cast <int *>(reinterpret_cast <char *>(result));
1564+ EXPECT_TRUE (*obj == 42 );
1565+
1566+ // Destructors
1567+ Cpp::TCppScope_t scope_C = Cpp::GetNamed (" C" );
1568+ Cpp::TCppObject_t object_C = Cpp::Construct (scope_C);
1569+
1570+ // Make destructor callable and pass arguments
1571+ JC = Cpp::MakeFunctionCallable (SubDecls[4 ]);
1572+ EXPECT_DEATH (
1573+ { JC.Invoke (&object_C, {args0, 1 }); },
1574+ " Destructor called with arguments" );
1575+ }
1576+ #endif // _WIN32
1577+ #endif
1578+
14941579template <typename T> T instantiation_in_host () { return T (0 ); }
14951580#if defined(_WIN32)
14961581template __declspec(dllexport) int instantiation_in_host<int >();
0 commit comments