Fix http://stackoverflow.com/questions/13521163
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 6 Dec 2012 06:44:44 +0000 (06:44 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 6 Dec 2012 06:44:44 +0000 (06:44 +0000)
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.

llvm-svn: 169475

clang/lib/Sema/SemaTemplateDeduction.cpp
clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp

index 77d76a4..7c5a596 100644 (file)
@@ -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;
 }
 
index 7774b5c..d7989e3 100644 (file)
@@ -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'}}
+  }
+}