]> granicus.if.org Git - clang/commitdiff
Sema: Reject templates in all extern "C" contexts.
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 2 Feb 2014 16:35:43 +0000 (16:35 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 2 Feb 2014 16:35:43 +0000 (16:35 +0000)
Otherwise we'd accept them if the LinkageDecl was not the direct
parent DeclContext. PR17968.

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

lib/Sema/SemaTemplate.cpp
test/SemaCXX/warn-unused-value.cpp
test/SemaTemplate/class-template-decl.cpp

index 008ed2755c2854d031221ee91a35248bd405be99..bc66fdedb6bf6186f9869329cdda0f4851f0ee1b 100644 (file)
@@ -5453,18 +5453,19 @@ Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
          (S->getFlags() & Scope::TemplateParamScope) != 0)
     S = S->getParent();
 
-  // C++ [temp]p2:
-  //   A template-declaration can appear only as a namespace scope or
-  //   class scope declaration.
+  // C++ [temp]p4:
+  //   A template [...] shall not have C linkage.
   DeclContext *Ctx = S->getEntity();
-  if (Ctx && isa<LinkageSpecDecl>(Ctx) &&
-      cast<LinkageSpecDecl>(Ctx)->getLanguage() != LinkageSpecDecl::lang_cxx)
+  if (Ctx && Ctx->isExternCContext())
     return Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
              << TemplateParams->getSourceRange();
 
   while (Ctx && isa<LinkageSpecDecl>(Ctx))
     Ctx = Ctx->getParent();
 
+  // C++ [temp]p2:
+  //   A template-declaration can appear only as a namespace scope or
+  //   class scope declaration.
   if (Ctx) {
     if (Ctx->isFileContext())
       return false;
index 5e43d3ec04222351c61553bf8e8325d204a2d0e4..4e1347cc307a52d9759ee98f16467070b4e236d1 100644 (file)
@@ -32,7 +32,7 @@ void b(Foo f1, Foo f2) {
 }
 
 namespace test2 {
-  extern "C" {
+  extern "C++" {
     namespace std {
       template<typename T> struct basic_string {
         struct X {};
index e65da2b312f63c2736dd2098f8afa777e852780a..b721aab35464599d2dd197e5b068831953effc3d 100644 (file)
@@ -14,6 +14,13 @@ extern "C" {
   template<typename T> class D; // expected-error{{templates must have C++ linkage}}
 }
 
+extern "C" {
+  class PR17968 {
+    template<typename T> class D; // expected-error{{templates must have C++ linkage}}
+    template<typename T> void f(); // expected-error{{templates must have C++ linkage}}
+  };
+}
+
 template<class U> class A; // expected-note{{previous template declaration is here}}
 
 template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}