From: David Majnemer Date: Mon, 30 Nov 2015 20:34:28 +0000 (+0000) Subject: [MS Compat] Adjust thiscall to cdecl when deducing template arguments X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e63176229a74ea43a824d1d55b826aa71345305e;p=clang [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 --- diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 2605acddfa..4b811c7e25 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -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; diff --git a/test/SemaCXX/calling-conv-compat.cpp b/test/SemaCXX/calling-conv-compat.cpp index cebac9fad6..20d93b41e1 100644 --- a/test/SemaCXX/calling-conv-compat.cpp +++ b/test/SemaCXX/calling-conv-compat.cpp @@ -370,6 +370,19 @@ X::p tmpl6 = &A::method_thiscall; X::p tmpl7 = &A::method_stdcall; X::p tmpl8 = &A::method_fastcall; +// Make sure we adjust thiscall to cdecl when extracting the function type from +// a member pointer. +template struct Y; + +template +struct Y { + typedef Fn *p; +}; + +void __cdecl f_cdecl(); +Y::p tmpl9 = &f_cdecl; + + } // end namespace MemberPointers // Test that lambdas that capture nothing convert to cdecl function pointers.