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

Commit

Permalink
[MS Compat] Adjust thiscall to cdecl when deducing template arguments
Browse files Browse the repository at this point in the history
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
  • Loading branch information
majnemer committed Nov 30, 2015
1 parent 34c8721 commit e631762
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
13 changes: 11 additions & 2 deletions lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1517,10 +1517,19 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
if (!MemPtrArg)
return Sema::TDK_NonDeducedMismatch;

QualType ParamPointeeType = MemPtrParam->getPointeeType();
if (ParamPointeeType->isFunctionType())
S.adjustMemberFunctionCC(ParamPointeeType, /*IsStatic=*/true,
/*IsCtorOrDtor=*/false, Info.getLocation());
QualType ArgPointeeType = MemPtrArg->getPointeeType();
if (ArgPointeeType->isFunctionType())
S.adjustMemberFunctionCC(ArgPointeeType, /*IsStatic=*/true,
/*IsCtorOrDtor=*/false, Info.getLocation());

if (Sema::TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(S, TemplateParams,
MemPtrParam->getPointeeType(),
MemPtrArg->getPointeeType(),
ParamPointeeType,
ArgPointeeType,
Info, Deduced,
TDF & TDF_IgnoreQualifiers))
return Result;
Expand Down
13 changes: 13 additions & 0 deletions test/SemaCXX/calling-conv-compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,19 @@ X<fun_cdecl >::p tmpl6 = &A::method_thiscall;
X<fun_stdcall >::p tmpl7 = &A::method_stdcall;
X<fun_fastcall>::p tmpl8 = &A::method_fastcall;

// Make sure we adjust thiscall to cdecl when extracting the function type from
// a member pointer.
template <typename> struct Y;

template <typename Fn, typename C>
struct Y<Fn C::*> {
typedef Fn *p;
};

void __cdecl f_cdecl();
Y<decltype(&A::method_thiscall)>::p tmpl9 = &f_cdecl;


} // end namespace MemberPointers

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

0 comments on commit e631762

Please sign in to comment.