[PATCH] D41179: [Sema] Diagnose template specializations with C linkage

Mikhail Maltsev via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 27 07:05:24 PST 2017


miyuki updated this revision to Diff 128234.
miyuki added a comment.

Factored out template language linkage check into a separate function


https://reviews.llvm.org/D41179

Files:
  lib/Sema/SemaTemplate.cpp
  test/SemaTemplate/class-template-spec.cpp
  test/SemaTemplate/function-template-specialization.cpp


Index: test/SemaTemplate/function-template-specialization.cpp
===================================================================
--- test/SemaTemplate/function-template-specialization.cpp
+++ test/SemaTemplate/function-template-specialization.cpp
@@ -56,3 +56,8 @@
   template<>
   static void Bar(const long& input) {}  // expected-error{{explicit specialization of 'Bar' in class scope}}
 };
+
+template<typename T> void f3(T) {}
+extern "C" { // expected-note {{extern "C" language linkage specification begins here}}
+  template<> void f3(int) {} // expected-error{{templates must have C++ linkage}}
+}
Index: test/SemaTemplate/class-template-spec.cpp
===================================================================
--- test/SemaTemplate/class-template-spec.cpp
+++ test/SemaTemplate/class-template-spec.cpp
@@ -235,3 +235,9 @@
   > struct S;
   template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
 }
+
+template<typename T> struct C {};
+extern "C" { // expected-note 2{{extern "C" language linkage specification begins here}}
+  template<typename T> struct C<T*> {}; // expected-error{{templates must have C++ linkage}}
+  template<> struct C<int> {}; // expected-error{{templates must have C++ linkage}}
+}
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -6953,6 +6953,21 @@
   return true;
 }
 
+/// \brief Check whether a template is declared with "C" language linkage.
+///
+/// If a template or a template specialization is declared with "C" language
+/// linkage, issues a diagnostic and returns true. Otherwise, returns false.
+static bool
+CheckTemplateLanguageLinkage(Sema &S, DeclContext *Ctx, SourceRange Rng) {
+  if (Ctx && Ctx->isExternCContext()) {
+    S.Diag(Rng.getBegin(), diag::err_template_linkage) << Rng;
+    if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
+      S.Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+    return true;
+  }
+  return false;
+}
+
 /// \brief Check whether a template can be declared within this scope.
 ///
 /// If the template declaration is valid in this scope, returns
@@ -6970,13 +6985,10 @@
   // C++ [temp]p4:
   //   A template [...] shall not have C linkage.
   DeclContext *Ctx = S->getEntity();
-  if (Ctx && Ctx->isExternCContext()) {
-    Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
-        << TemplateParams->getSourceRange();
-    if (const LinkageSpecDecl *LSD = Ctx->getExternCContext())
-      Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
+  if (CheckTemplateLanguageLinkage(*this, Ctx,
+                                   TemplateParams->getSourceRange()))
     return true;
-  }
+
   Ctx = Ctx->getRedeclContext();
 
   // C++ [temp]p2:
@@ -7071,6 +7083,12 @@
     return true;
   }
 
+  // C++ [temp]p6:
+  //   A template, a template explicit specialization, and a class template
+  //   partial specialization shall not have C linkage.
+  if (CheckTemplateLanguageLinkage(S, S.CurContext, Loc))
+    return true;
+
   // C++ [temp.expl.spec]p2:
   //   An explicit specialization shall be declared in the namespace
   //   of which the template is a member, or, for member templates, in


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41179.128234.patch
Type: text/x-patch
Size: 3342 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171227/a565bbbb/attachment.bin>


More information about the cfe-commits mailing list