Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit e631762

Browse files
committed
[MS Compat] Adjust thiscall to cdecl when deducing template arguments
Function types can be extracted from member pointer types. However, the type is not appropriate without first adjusting the calling convention. This fixes PR25661. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@254323 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 34c8721 commit e631762

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,10 +1517,19 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
15171517
if (!MemPtrArg)
15181518
return Sema::TDK_NonDeducedMismatch;
15191519

1520+
QualType ParamPointeeType = MemPtrParam->getPointeeType();
1521+
if (ParamPointeeType->isFunctionType())
1522+
S.adjustMemberFunctionCC(ParamPointeeType, /*IsStatic=*/true,
1523+
/*IsCtorOrDtor=*/false, Info.getLocation());
1524+
QualType ArgPointeeType = MemPtrArg->getPointeeType();
1525+
if (ArgPointeeType->isFunctionType())
1526+
S.adjustMemberFunctionCC(ArgPointeeType, /*IsStatic=*/true,
1527+
/*IsCtorOrDtor=*/false, Info.getLocation());
1528+
15201529
if (Sema::TemplateDeductionResult Result
15211530
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
1522-
MemPtrParam->getPointeeType(),
1523-
MemPtrArg->getPointeeType(),
1531+
ParamPointeeType,
1532+
ArgPointeeType,
15241533
Info, Deduced,
15251534
TDF & TDF_IgnoreQualifiers))
15261535
return Result;

test/SemaCXX/calling-conv-compat.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,19 @@ X<fun_cdecl >::p tmpl6 = &A::method_thiscall;
370370
X<fun_stdcall >::p tmpl7 = &A::method_stdcall;
371371
X<fun_fastcall>::p tmpl8 = &A::method_fastcall;
372372

373+
// Make sure we adjust thiscall to cdecl when extracting the function type from
374+
// a member pointer.
375+
template <typename> struct Y;
376+
377+
template <typename Fn, typename C>
378+
struct Y<Fn C::*> {
379+
typedef Fn *p;
380+
};
381+
382+
void __cdecl f_cdecl();
383+
Y<decltype(&A::method_thiscall)>::p tmpl9 = &f_cdecl;
384+
385+
373386
} // end namespace MemberPointers
374387

375388
// Test that lambdas that capture nothing convert to cdecl function pointers.

0 commit comments

Comments
 (0)