]> granicus.if.org Git - clang/commitdiff
When checking the instantiation of a default template argument against
authorDouglas Gregor <dgregor@apple.com>
Fri, 3 Jun 2011 02:59:40 +0000 (02:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 3 Jun 2011 02:59:40 +0000 (02:59 +0000)
the template parameter, perform the checking as a "specified" template
argument rather than a "deduced" template argument; the latter implies
stricter type checking that is not permitted for default template
arguments.

Also, cleanup our handling of substitution of explicit template
arguments for a function template. We were actually performing some
substitution of default arguments at this point!

Fixes PR10069.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132529 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateDeduction.cpp
test/CXX/temp/temp.param/p9-0x.cpp

index 1aa7364d183e7d15107225313a6558df40f34dd8..3761740d8c038480a43c69c3452279c7c634dd75 100644 (file)
@@ -2819,9 +2819,6 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
   unsigned ArgIdx = 0;
   LocalInstantiationScope InstScope(*this, true);
   while (Param != ParamEnd) {
-    if (ArgIdx > NumArgs && PartialTemplateArgs)
-      break;
-
     if (ArgIdx < NumArgs) {
       // If we have an expanded parameter pack, make sure we don't have too
       // many arguments.
@@ -2862,6 +2859,16 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
       continue;
     }
 
+    // If we're checking a partial template argument list, we're done.
+    if (PartialTemplateArgs) {
+      if ((*Param)->isTemplateParameterPack() && !ArgumentPack.empty())
+        Converted.push_back(TemplateArgument::CreatePackCopy(Context,
+                                                         ArgumentPack.data(),
+                                                         ArgumentPack.size()));
+        
+      return Invalid;
+    }
+
     // If we have a template parameter pack with no more corresponding
     // arguments, just break out now and we'll fill in the argument pack below.
     if ((*Param)->isTemplateParameterPack())
@@ -2887,7 +2894,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
     // the default argument.
     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
       if (!TTP->hasDefaultArgument()) {
-        assert((Invalid || PartialTemplateArgs) && "Missing default argument");
+        assert(Invalid && "Missing default argument");
         break;
       }
 
@@ -2905,7 +2912,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
     } else if (NonTypeTemplateParmDecl *NTTP
                  = dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
       if (!NTTP->hasDefaultArgument()) {
-        assert((Invalid || PartialTemplateArgs) && "Missing default argument");
+        assert(Invalid && "Missing default argument");
         break;
       }
 
@@ -2924,7 +2931,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
         = cast<TemplateTemplateParmDecl>(*Param);
 
       if (!TempParm->hasDefaultArgument()) {
-        assert((Invalid || PartialTemplateArgs) && "Missing default argument");
+        assert(Invalid && "Missing default argument");
         break;
       }
 
@@ -2970,9 +2977,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
     // in arguments for non-template parameter packs.
 
     if ((*Param)->isTemplateParameterPack()) {
-      if (PartialTemplateArgs && ArgumentPack.empty()) {
-        Converted.push_back(TemplateArgument());
-      } else if (ArgumentPack.empty())
+      if (ArgumentPack.empty())
         Converted.push_back(TemplateArgument(0, 0));
       else {
         Converted.push_back(TemplateArgument::CreatePackCopy(Context,
index c4627eb1e3a9ce4f63d5ad70677339aab7265e22..ed1b671bf4a32410e5dac967e17f4bcd1540172a 100644 (file)
@@ -2314,7 +2314,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
                               FunctionTemplate->getLocation(),
                               FunctionTemplate->getSourceRange().getEnd(),
                               0, Builder,
-                              CTAK_Deduced)) {
+                              CTAK_Specified)) {
       Info.Param = makeTemplateParameter(
                          const_cast<NamedDecl *>(TemplateParams->getParam(I)));
       // FIXME: These template arguments are temporary. Free them!
index 17eca7f7e85dd4abd282edec2d6578c2c9c89aa3..1dc6640fe26662473dd351590b81e95cab8ad7c4 100644 (file)
@@ -50,3 +50,12 @@ namespace PR8748 {
   template<typename T = int> struct Inner::X3 { };
   template<typename T = int> void Inner::f2() {}
 }
+
+namespace PR10069 {
+  template<typename T, T a, T b=0, T c=1>
+  T f(T x);
+
+  void g() {
+    f<unsigned int, 0>(0);
+  }
+}