[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