diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-12-06 06:44:44 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-12-06 06:44:44 +0000 |
commit | 030a6644f253818b81b4d8a7fc1770c0a3d35474 (patch) | |
tree | 3ce9e3b92f9012a21e890e2dd7f38d86389b8703 | |
parent | d5e839429771ad4d1a8b3db598cbbc6d93621f75 (diff) |
Fix http://stackoverflow.com/questions/13521163
Don't require that, during template deduction, a template specialization type
as a function parameter has at least as many template arguments as one used in
a function argument (not even if the argument has been resolved to an exact
type); the additional parameters might be provided by default template
arguments in the template. We don't need this check, since we now implement
[temp.deduct.call]p4 with an additional check after deduction.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169475 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 17 | ||||
-rw-r--r-- | test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp | 13 |
2 files changed, 17 insertions, 13 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 77d76a4fd3..7c5a59671d 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -130,8 +130,7 @@ DeduceTemplateArguments(Sema &S, const TemplateArgument *Params, unsigned NumParams, const TemplateArgument *Args, unsigned NumArgs, TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - bool NumberOfArgumentsMustMatch = true); + SmallVectorImpl<DeducedTemplateArgument> &Deduced); /// \brief If the given expression is of a form that permits the deduction /// of a non-type template parameter, return the declaration of that @@ -482,8 +481,7 @@ DeduceTemplateArguments(Sema &S, return DeduceTemplateArguments(S, TemplateParams, Param->getArgs(), Param->getNumArgs(), SpecArg->getArgs(), SpecArg->getNumArgs(), - Info, Deduced, - /*NumberOfArgumentsMustMatch=*/false); + Info, Deduced); } // If the argument type is a class template specialization, we @@ -1749,8 +1747,7 @@ DeduceTemplateArguments(Sema &S, const TemplateArgument *Params, unsigned NumParams, const TemplateArgument *Args, unsigned NumArgs, TemplateDeductionInfo &Info, - SmallVectorImpl<DeducedTemplateArgument> &Deduced, - bool NumberOfArgumentsMustMatch) { + SmallVectorImpl<DeducedTemplateArgument> &Deduced) { // C++0x [temp.deduct.type]p9: // If the template argument list of P contains a pack expansion that is not // the last template argument, the entire template argument list is a @@ -1770,8 +1767,7 @@ DeduceTemplateArguments(Sema &S, // Check whether we have enough arguments. if (!hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs)) - return NumberOfArgumentsMustMatch? Sema::TDK_NonDeducedMismatch - : Sema::TDK_Success; + return Sema::TDK_Success; if (Args[ArgIdx].isPackExpansion()) { // FIXME: We follow the logic of C++0x [temp.deduct.type]p22 here, @@ -1867,11 +1863,6 @@ DeduceTemplateArguments(Sema &S, return Result; } - // If there is an argument remaining, then we had too many arguments. - if (NumberOfArgumentsMustMatch && - hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs)) - return Sema::TDK_NonDeducedMismatch; - return Sema::TDK_Success; } diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp index 7774b5c77f..d7989e305f 100644 --- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp +++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp @@ -53,3 +53,16 @@ namespace DeduceNonTypeTemplateArgsInArray { tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>> >::value? 1 : -1]; } + +namespace DeduceWithDefaultArgs { + template<template<typename...> class Container> void f(Container<int>); // expected-note {{substitution failure [with Container = X]}} + template<typename, typename = int> struct X {}; + void g() { + // OK, use default argument for the second template parameter. + f(X<int>{}); + f(X<int, int>{}); + + // Not OK. + f(X<int, double>{}); // expected-error {{no matching function for call to 'f'}} + } +} |