summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2014-02-02 16:35:43 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2014-02-02 16:35:43 +0000
commit35e6fee3e9a0c7ee1828fbfb31da08298d9881f8 (patch)
treefc2e9382bffc4b3baf8cade53ed19c8d92e60b6d /clang
parent3a7cc81d52f9b7a6e7e94c9efcd1113f1aeb8c9a (diff)
downloadbcm5719-llvm-35e6fee3e9a0c7ee1828fbfb31da08298d9881f8.tar.gz
bcm5719-llvm-35e6fee3e9a0c7ee1828fbfb31da08298d9881f8.zip
Sema: Reject templates in all extern "C" contexts.
Otherwise we'd accept them if the LinkageDecl was not the direct parent DeclContext. PR17968. llvm-svn: 200641
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp11
-rw-r--r--clang/test/SemaCXX/warn-unused-value.cpp2
-rw-r--r--clang/test/SemaTemplate/class-template-decl.cpp7
3 files changed, 14 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 008ed2755c2..bc66fdedb6b 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -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;
diff --git a/clang/test/SemaCXX/warn-unused-value.cpp b/clang/test/SemaCXX/warn-unused-value.cpp
index 5e43d3ec042..4e1347cc307 100644
--- a/clang/test/SemaCXX/warn-unused-value.cpp
+++ b/clang/test/SemaCXX/warn-unused-value.cpp
@@ -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 {};
diff --git a/clang/test/SemaTemplate/class-template-decl.cpp b/clang/test/SemaTemplate/class-template-decl.cpp
index e65da2b312f..b721aab3546 100644
--- a/clang/test/SemaTemplate/class-template-decl.cpp
+++ b/clang/test/SemaTemplate/class-template-decl.cpp
@@ -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}}
OpenPOWER on IntegriCloud