Skip to content

Commit a5b4c5e

Browse files
fix: overload resolution for template pack of rvalue reference
1 parent 2df83a9 commit a5b4c5e

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

lib/CppInterOp/CppInterOp.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,9 @@ BestOverloadFunctionMatch(const std::vector<TCppFunction_t>& candidates,
12331233
size_t idx = 0;
12341234
for (auto i : arg_types) {
12351235
QualType Type = QualType::getFromOpaquePtr(i.m_Type);
1236-
ExprValueKind ExprKind = ExprValueKind::VK_PRValue;
1236+
// XValue is an object that can be "moved" whereas PRValue is temporary
1237+
// value. This enables overloads that require the object to be moved
1238+
ExprValueKind ExprKind = ExprValueKind::VK_XValue;
12371239
if (Type->isLValueReferenceType())
12381240
ExprKind = ExprValueKind::VK_LValue;
12391241

unittests/CppInterOp/FunctionReflectionTest.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,48 @@ TYPED_TEST(CppInterOpTest, FunctionReflectionTestBestOverloadFunctionMatch4) {
12721272
"template<> void B::fn<int, int>(A<int> x, A<int> y)");
12731273
}
12741274

1275+
TYPED_TEST(CppInterOpTest, FunctionReflectionTestBestOverloadFunctionMatch5) {
1276+
std::vector<Decl*> Decls;
1277+
std::string code = R"(
1278+
template<typename T1, typename T2>
1279+
void callme(T1 t1, T2 t2) {}
1280+
1281+
template <typename F, typename... Args>
1282+
void callback(F callable, Args&&... args) {
1283+
callable(args...);
1284+
}
1285+
)";
1286+
GetAllTopLevelDecls(code, Decls);
1287+
EXPECT_EQ(Decls.size(), 2);
1288+
1289+
std::vector<Cpp::TCppFunction_t> candidates;
1290+
candidates.push_back(Decls[1]);
1291+
1292+
ASTContext& C = Interp->getCI()->getASTContext();
1293+
std::vector<Cpp::TemplateArgInfo> explicit_params = {
1294+
C.DoubleTy.getAsOpaquePtr(),
1295+
C.IntTy.getAsOpaquePtr(),
1296+
};
1297+
1298+
Cpp::TCppScope_t callme = Cpp::InstantiateTemplate(
1299+
Decls[0], explicit_params.data(), explicit_params.size());
1300+
EXPECT_TRUE(callme);
1301+
1302+
std::vector<Cpp::TemplateArgInfo> arg_types = {
1303+
Cpp::GetTypeFromScope(callme),
1304+
C.getLValueReferenceType(C.DoubleTy).getAsOpaquePtr(),
1305+
C.getLValueReferenceType(C.IntTy).getAsOpaquePtr(),
1306+
};
1307+
1308+
Cpp::TCppScope_t callback =
1309+
Cpp::BestOverloadFunctionMatch(candidates, {}, arg_types);
1310+
EXPECT_TRUE(callback);
1311+
1312+
EXPECT_EQ(Cpp::GetFunctionSignature(callback),
1313+
"template<> void callback<void (*)(double, int), <double &, int "
1314+
"&>>(void (*callable)(double, int), double &args, int &args)");
1315+
}
1316+
12751317
TYPED_TEST(CppInterOpTest, FunctionReflectionTestIsPublicMethod) {
12761318
std::vector<Decl *> Decls, SubDecls;
12771319
std::string code = R"(

0 commit comments

Comments
 (0)