From: Douglas Gregor Date: Wed, 29 Sep 2010 21:14:36 +0000 (+0000) Subject: When performing template argument deduction of a function template X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fbb6fad63acac2bef36cfa13e0706fa3e2a1ed7d;p=clang When performing template argument deduction of a function template against a function type, be sure to check the type of the resulting function template specialization against the desired function type after substituting the deduced/defaulted template arguments. Fixes PR8196. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115086 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 919aea8d02..92d68bba66 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -6348,8 +6348,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, // FIXME: make a note of the failed deduction for diagnostics. (void)Result; } else { - // FIXME: If the match isn't exact, shouldn't we just drop this as - // a candidate? Find a testcase before changing the code. + // Template argument deduction ensures that we have an exact match. + // This function template specicalization works. assert(FunctionType == Context.getCanonicalType(Specialization->getType())); Matches.push_back(std::make_pair(I.getPair(), diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 5c77ed6106..f3ffa716f1 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -1865,10 +1865,20 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, Deduced, 0)) return Result; } - - return FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, - NumExplicitlySpecified, - Specialization, Info); + + if (TemplateDeductionResult Result + = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, + NumExplicitlySpecified, + Specialization, Info)) + return Result; + + // If the requested function type does not match the actual type of the + // specialization, template argument deduction fails. + if (!ArgFunctionType.isNull() && + !Context.hasSameType(ArgFunctionType, Specialization->getType())) + return TDK_NonDeducedMismatch; + + return TDK_Success; } /// \brief Deduce template arguments for a templated conversion diff --git a/test/SemaCXX/addr-of-overloaded-function.cpp b/test/SemaCXX/addr-of-overloaded-function.cpp index 46bdf8e6b6..ab80d8f141 100644 --- a/test/SemaCXX/addr-of-overloaded-function.cpp +++ b/test/SemaCXX/addr-of-overloaded-function.cpp @@ -104,3 +104,15 @@ namespace PR8033 { // expected-error{{cannot initialize a variable of type}} } + +namespace PR8196 { + template struct mcdata { + typedef int result_type; + }; + template + typename mcdata::result_type wrap_mean(mcdata const&); + void add_property(double(*)(mcdata const &)); // expected-note{{candidate function not viable: no overload of 'wrap_mean' matching}} + void f() { + add_property(&wrap_mean); // expected-error{{no matching function for call to 'add_property'}} + } +}