@@ -1491,6 +1491,91 @@ TEST(FunctionReflectionTest, JitCallAdvanced) {
1491
1491
clang_Interpreter_dispose (I);
1492
1492
}
1493
1493
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
+
1494
1579
template <typename T> T instantiation_in_host () { return T (0 ); }
1495
1580
#if defined(_WIN32)
1496
1581
template __declspec(dllexport) int instantiation_in_host<int >();
0 commit comments