Skip to content

Commit 2ced7b8

Browse files
committed
Properly implement placement new via Cpp::Construct.
This patch should fix the valgrind issues.
1 parent 9dfb86e commit 2ced7b8

File tree

2 files changed

+11
-35
lines changed

2 files changed

+11
-35
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,10 +1410,10 @@ namespace Cpp {
14101410
const std::string& class_name, int indent_level) {
14111411
// Make a code string that follows this pattern:
14121412
//
1413-
// new ClassName(args...)
1413+
// ClassName(args...)
14141414
//
14151415

1416-
callbuf << "new " << class_name << "(";
1416+
callbuf << class_name << "(";
14171417
for (unsigned i = 0U; i < N; ++i) {
14181418
const ParmVarDecl* PVD = FD->getParamDecl(i);
14191419
QualType Ty = PVD->getType();
@@ -1575,16 +1575,9 @@ namespace Cpp {
15751575
std::ostringstream& buf, int indent_level) {
15761576
// Make a code string that follows this pattern:
15771577
//
1578-
// if (ret) {
1579-
// (*(ClassName**)ret) = new ClassName(args...);
1580-
// }
1581-
// else {
1582-
// new ClassName(args...);
1583-
// }
1578+
// (*(ClassName**)ret) = (obj) ?
1579+
// new (*(ClassName**)ret) ClassName(args...) : new ClassName(args...);
15841580
//
1585-
indent(buf, indent_level);
1586-
buf << "if (ret) {\n";
1587-
++indent_level;
15881581
{
15891582
std::ostringstream typedefbuf;
15901583
std::ostringstream callbuf;
@@ -1593,40 +1586,23 @@ namespace Cpp {
15931586
//
15941587
indent(callbuf, indent_level);
15951588
callbuf << "(*(" << class_name << "**)ret) = ";
1589+
callbuf << "(obj) ? new (*(" << class_name << "**)ret) ";
1590+
make_narg_ctor(FD, N, typedefbuf, callbuf, class_name, indent_level);
1591+
1592+
callbuf << ": new ";
15961593
//
1597-
// Write the actual new expression.
1594+
// Write the actual expression.
15981595
//
15991596
make_narg_ctor(FD, N, typedefbuf, callbuf, class_name, indent_level);
16001597
//
16011598
// End the new expression statement.
16021599
//
16031600
callbuf << ";\n";
1604-
indent(callbuf, indent_level);
1605-
callbuf << "return;\n";
16061601
//
16071602
// Output the whole new expression and return statement.
16081603
//
16091604
buf << typedefbuf.str() << callbuf.str();
16101605
}
1611-
--indent_level;
1612-
indent(buf, indent_level);
1613-
buf << "}\n";
1614-
indent(buf, indent_level);
1615-
buf << "else {\n";
1616-
++indent_level;
1617-
{
1618-
std::ostringstream typedefbuf;
1619-
std::ostringstream callbuf;
1620-
indent(callbuf, indent_level);
1621-
make_narg_ctor(FD, N, typedefbuf, callbuf, class_name, indent_level);
1622-
callbuf << ";\n";
1623-
indent(callbuf, indent_level);
1624-
callbuf << "return;\n";
1625-
buf << typedefbuf.str() << callbuf.str();
1626-
}
1627-
--indent_level;
1628-
indent(buf, indent_level);
1629-
buf << "}\n";
16301606
}
16311607

16321608
void make_narg_call_with_return(compat::Interpreter& I,
@@ -2838,7 +2814,7 @@ namespace Cpp {
28382814
auto* const Ctor = GetDefaultConstructor(Class);
28392815
if (JitCall JC = MakeFunctionCallable(Ctor)) {
28402816
if (arena) {
2841-
JC.Invoke(arena);
2817+
JC.Invoke(&arena, {}, (void *)~0U); // Tell Invoke to use placement new.
28422818
return arena;
28432819
}
28442820

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ TEST(FunctionReflectionTest, Construct) {
738738
void* where = Cpp::Allocate(scope);
739739
EXPECT_TRUE(where == Cpp::Construct(scope, where));
740740
// Check for the value of x which should be at the start of the object.
741-
EXPECT_TRUE(**(int **)(void **)where == 12345);
741+
EXPECT_TRUE(*(int *)where == 12345);
742742
Cpp::Deallocate(scope, where);
743743
output = testing::internal::GetCapturedStdout();
744744
EXPECT_EQ(output, "Constructor Executed");

0 commit comments

Comments
 (0)