[cfe-commits] r142473 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.param/p11-0x.cpp

David Blaikie dblaikie at gmail.com
Tue Oct 18 22:19:51 PDT 2011


Author: dblaikie
Date: Wed Oct 19 00:19:50 2011
New Revision: 142473

URL: http://llvm.org/viewvc/llvm-project?rev=142473&view=rev
Log:
Fix pr9789, assert-on-invalid while instantiating an (invalid) class template with a non-final parameter pack. Also improve the warning for non-final parameter packs in this scenario so it only fires once, rather than once for every template parameter after the non-final parameter pack.

Modified:
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=142473&r1=142472&r2=142473&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Oct 19 00:19:50 2011
@@ -1195,9 +1195,6 @@
   bool SawDefaultArgument = false;
   SourceLocation PreviousDefaultArgLoc;
 
-  bool SawParameterPack = false;
-  SourceLocation ParameterPackLoc;
-
   // Dummy initialization to avoid warnings.
   TemplateParameterList::iterator OldParam = NewParams->end();
   if (OldParams)
@@ -1212,18 +1209,11 @@
     SourceLocation OldDefaultLoc;
     SourceLocation NewDefaultLoc;
 
-    // Variables used to diagnose missing default arguments
+    // Variable used to diagnose missing default arguments
     bool MissingDefaultArg = false;
 
-    // C++0x [temp.param]p11:
-    //   If a template parameter of a primary class template or alias template
-    //   is a template parameter pack, it shall be the last template parameter.
-    if (SawParameterPack &&
-        (TPC == TPC_ClassTemplate || TPC == TPC_TypeAliasTemplate)) {
-      Diag(ParameterPackLoc,
-           diag::err_template_param_pack_must_be_last_template_parameter);
-      Invalid = true;
-    }
+    // Variable used to diagnose non-final parameter packs
+    bool SawParameterPack = false;
 
     if (TemplateTypeParmDecl *NewTypeParm
           = dyn_cast<TemplateTypeParmDecl>(*NewParam)) {
@@ -1243,7 +1233,6 @@
         assert(!NewTypeParm->hasDefaultArgument() &&
                "Parameter packs can't have a default argument!");
         SawParameterPack = true;
-        ParameterPackLoc = NewTypeParm->getLocation();
       } else if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
                  NewTypeParm->hasDefaultArgument()) {
         OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
@@ -1288,7 +1277,6 @@
         assert(!NewNonTypeParm->hasDefaultArgument() &&
                "Parameter packs can't have a default argument!");
         SawParameterPack = true;
-        ParameterPackLoc = NewNonTypeParm->getLocation();
       } else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() &&
           NewNonTypeParm->hasDefaultArgument()) {
         OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc();
@@ -1313,7 +1301,6 @@
       } else if (SawDefaultArgument)
         MissingDefaultArg = true;
     } else {
-      // Check the presence of a default argument here.
       TemplateTemplateParmDecl *NewTemplateParm
         = cast<TemplateTemplateParmDecl>(*NewParam);
 
@@ -1323,6 +1310,7 @@
         continue;
       }
 
+      // Check the presence of a default argument here.
       if (NewTemplateParm->hasDefaultArgument() &&
           DiagnoseDefaultTemplateArgument(*this, TPC,
                                           NewTemplateParm->getLocation(),
@@ -1336,7 +1324,6 @@
         assert(!NewTemplateParm->hasDefaultArgument() &&
                "Parameter packs can't have a default argument!");
         SawParameterPack = true;
-        ParameterPackLoc = NewTemplateParm->getLocation();
       } else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() &&
           NewTemplateParm->hasDefaultArgument()) {
         OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation();
@@ -1363,6 +1350,16 @@
         MissingDefaultArg = true;
     }
 
+    // C++0x [temp.param]p11:
+    //   If a template parameter of a primary class template or alias template
+    //   is a template parameter pack, it shall be the last template parameter.
+    if (SawParameterPack && (NewParam + 1) != NewParamEnd && 
+        (TPC == TPC_ClassTemplate || TPC == TPC_TypeAliasTemplate)) {
+      Diag((*NewParam)->getLocation(),
+           diag::err_template_param_pack_must_be_last_template_parameter);
+      Invalid = true;
+    }
+
     if (RedundantDefaultArg) {
       // C++ [temp.param]p12:
       //   A template-parameter shall not be given default arguments
@@ -3047,6 +3044,8 @@
     // in arguments for non-template parameter packs.
 
     if ((*Param)->isTemplateParameterPack()) {
+      if (!HasParameterPack)
+        return true;
       if (ArgumentPack.empty())
         Converted.push_back(TemplateArgument(0, 0));
       else {

Modified: cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp?rev=142473&r1=142472&r2=142473&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.param/p11-0x.cpp Wed Oct 19 00:19:50 2011
@@ -24,8 +24,9 @@
 // If a template-parameter of a primary class template or alias template is a
 // template parameter pack, it shall be the last template-parameter.
 template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
-         int After>
+         int After, int After2>
 struct X0t;
+X0t<int> pr9789();
 template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
          int After>
 using A0t = int;





More information about the cfe-commits mailing list