Skip to content

Commit 64d02c5

Browse files
fix MakeFunctionCallable's codegen when return type is a function pointer
1 parent fc852d5 commit 64d02c5

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

lib/Interpreter/CppInterOp.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,7 @@ namespace Cpp {
16701670
//
16711671
ASTContext& C = FD->getASTContext();
16721672
PrintingPolicy Policy(C.getPrintingPolicy());
1673+
Policy.SuppressElaboration = 1;
16731674
refType = kNotReference;
16741675
if (QT->isRecordType() && forArgument) {
16751676
get_type_as_string(QT, type_name, C, Policy);
@@ -1984,18 +1985,22 @@ namespace Cpp {
19841985
EReferenceType refType = kNotReference;
19851986
bool isPointer = false;
19861987

1988+
std::ostringstream typedefbuf;
1989+
std::ostringstream callbuf;
1990+
1991+
collect_type_info(FD, QT, typedefbuf, callbuf, type_name, refType,
1992+
isPointer, indent_level, false);
1993+
1994+
buf << typedefbuf.str();
1995+
19871996
buf << "if (ret) {\n";
19881997
++indent_level;
19891998
{
1990-
std::ostringstream typedefbuf;
1991-
std::ostringstream callbuf;
19921999
//
19932000
// Write the placement part of the placement new.
19942001
//
19952002
indent(callbuf, indent_level);
19962003
callbuf << "new (ret) ";
1997-
collect_type_info(FD, QT, typedefbuf, callbuf, type_name, refType,
1998-
isPointer, indent_level, false);
19992004
//
20002005
// Write the type part of the placement new.
20012006
//

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,9 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
885885
int f3() { return 3; }
886886
887887
extern "C" int f4() { return 4; }
888+
889+
typedef int(*int_func)(void);
890+
int_func f5() { return f3; }
888891
}
889892
)");
890893

@@ -900,6 +903,9 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
900903
Cpp::JitCall FCI4 =
901904
Cpp::MakeFunctionCallable(Cpp::GetNamed("f4", Cpp::GetNamed("NS")));
902905
EXPECT_TRUE(FCI4.getKind() == Cpp::JitCall::kGenericCall);
906+
Cpp::JitCall FCI5 =
907+
Cpp::MakeFunctionCallable(Cpp::GetNamed("f5", Cpp::GetNamed("NS")));
908+
EXPECT_TRUE(FCI5.getKind() == Cpp::JitCall::kGenericCall);
903909

904910
int i = 9, ret1, ret3, ret4;
905911
std::string s("Hello World!\n");
@@ -920,6 +926,12 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
920926
FCI4.Invoke(&ret4);
921927
EXPECT_EQ(ret4, 4);
922928

929+
typedef int (*int_func)(void);
930+
int_func callback = nullptr;
931+
FCI5.Invoke(&callback);
932+
EXPECT_TRUE(callback);
933+
EXPECT_EQ(callback(), 3);
934+
923935
// FIXME: Do we need to support private ctors?
924936
Interp->process(R"(
925937
class C {

0 commit comments

Comments
 (0)