]> granicus.if.org Git - clang/commitdiff
Fix accepts-invalid if a variable template explicit instantiation is missing an
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 18 Sep 2013 02:10:12 +0000 (02:10 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 18 Sep 2013 02:10:12 +0000 (02:10 +0000)
argument list, but could be instantiated with argument list of <>.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaTemplate.cpp
test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
test/SemaCXX/cxx1y-variable-templates_top_level.cpp

index 9f620fefa15047a8a323e324fbb7f9708a8d435e..af5c6f60993d2abe483a6789448440208d3cc382 100644 (file)
@@ -3289,6 +3289,8 @@ def err_explicit_instantiation_constexpr : Error<
 def ext_explicit_instantiation_without_qualified_id : Extension<
   "qualifier in explicit instantiation of %q0 requires a template-id "
   "(a typedef is not permitted)">;
+def err_explicit_instantiation_without_template_id : Error<
+  "explicit instantiation of %q0 must specify a template argument list">;
 def err_explicit_instantiation_unqualified_wrong_namespace : Error<
   "explicit instantiation of %q0 must occur in namespace %1">;
 def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning<
index c5b97d608e28d2ade2ae0f92ff68e0491777c89f..f6863fb279967fea0edf8fa1f62fd7e280748dac 100644 (file)
@@ -7243,17 +7243,27 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
         return true;
       }
 
-      TemplateArgumentListInfo TemplateArgs;
-      if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
-        // Translate the parser's template argument list into our AST format.
-        TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
-        TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
-        TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
-        ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
-                                           TemplateId->NumArgs);
-        translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
+      if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
+        // C++1y [temp.explicit]p3:
+        //   If the explicit instantiation is for a variable, the unqualified-id
+        //   in the declaration shall be a template-id.
+        Diag(D.getIdentifierLoc(),
+             diag::err_explicit_instantiation_without_template_id)
+          << PrevTemplate;
+        Diag(PrevTemplate->getLocation(),
+             diag::note_explicit_instantiation_here);
+        return true;
       }
 
+      // Translate the parser's template argument list into our AST format.
+      TemplateArgumentListInfo TemplateArgs;
+      TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
+      TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
+      TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
+      ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
+                                         TemplateId->NumArgs);
+      translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
+
       DeclResult Res = CheckVarTemplateId(PrevTemplate, TemplateLoc,
                                           D.getIdentifierLoc(), TemplateArgs);
       if (Res.isInvalid())
index edaae9f49d0517ae21f26e2023da60b61cc45081..93f8ff1697bffa12ff93a6a5f9a6909c8e1a2b0d 100644 (file)
@@ -9,7 +9,7 @@ T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
 template int pi<int>;
 
 #ifndef FIXING
-template float pi; // expected-error {{too few template arguments for template 'pi'}}
+template float pi<>; // expected-error {{too few template arguments for template 'pi'}}
 template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}}
 #endif
 
index 49be0bdcbe253945c7b72dabf2e669c265d163c1..c98400cd878db7cfc7ebeb1d6635e2d24fbca1ef 100644 (file)
@@ -168,7 +168,10 @@ namespace explicit_instantiation {
     template int var<int>;
   }
 #endif
-  
+
+  template<typename=int> int missing_args; // expected-note {{here}}
+  template int missing_args; // expected-error {{must specify a template argument list}}
+
   namespace extern_var {
     // TODO:
   }