Skip to content

Commit 28abd17

Browse files
fix codegen & instantiation of templated function with rvalue as parameter (#633)
* fix codegen to not cast func if templated this is taken from cling * fix `BestOverloadFunctionMatch` to handle rvalues * add test
1 parent 7bb23b9 commit 28abd17

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

lib/CppInterOp/CppInterOp.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@ BestOverloadFunctionMatch(const std::vector<TCppFunction_t>& candidates,
11421142
for (auto i : arg_types) {
11431143
QualType Type = QualType::getFromOpaquePtr(i.m_Type);
11441144
ExprValueKind ExprKind = ExprValueKind::VK_PRValue;
1145-
if (Type->isReferenceType())
1145+
if (Type->isLValueReferenceType())
11461146
ExprKind = ExprValueKind::VK_LValue;
11471147

11481148
new (&Exprs[idx]) OpaqueValueExpr(SourceLocation::getFromRawEncoding(1),
@@ -1993,8 +1993,9 @@ void make_narg_call(const FunctionDecl* FD, const std::string& return_type,
19931993
bool op_flag = !FD->isOverloadedOperator() ||
19941994
FD->getOverloadedOperator() == clang::OO_Call;
19951995

1996-
bool ShouldCastFunction =
1997-
!isa<CXXMethodDecl>(FD) && N == FD->getNumParams() && op_flag;
1996+
bool ShouldCastFunction = !isa<CXXMethodDecl>(FD) &&
1997+
N == FD->getNumParams() && op_flag &&
1998+
!FD->isTemplateInstantiation();
19981999
if (ShouldCastFunction) {
19992000
callbuf << "(";
20002001
callbuf << "(";

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,26 @@ TEST(FunctionReflectionTest, GetFunctionCallWrapper) {
18361836
auto fn_callable = Cpp::MakeFunctionCallable(fn);
18371837
EXPECT_EQ(fn_callable.getKind(), Cpp::JitCall::kGenericCall);
18381838

1839+
Interp->process(R"(
1840+
template <typename T>
1841+
bool call_move(T&& t) {
1842+
return true;
1843+
}
1844+
)");
1845+
1846+
unresolved_candidate_methods.clear();
1847+
Cpp::GetClassTemplatedMethods("call_move", Cpp::GetGlobalScope(),
1848+
unresolved_candidate_methods);
1849+
EXPECT_EQ(unresolved_candidate_methods.size(), 1);
1850+
1851+
Cpp::TCppScope_t call_move = Cpp::BestOverloadFunctionMatch(
1852+
unresolved_candidate_methods, {},
1853+
{Cpp::GetReferencedType(Cpp::GetType("int"), true)});
1854+
EXPECT_TRUE(call_move);
1855+
1856+
auto call_move_callable = Cpp::MakeFunctionCallable(call_move);
1857+
EXPECT_EQ(call_move_callable.getKind(), Cpp::JitCall::kGenericCall);
1858+
18391859
// instantiation in host, no template function body
18401860
Interp->process("template<typename T> T instantiation_in_host();");
18411861

0 commit comments

Comments
 (0)