diff options
| author | Benjamin Kramer <benny.kra@googlemail.com> | 2014-02-02 16:35:43 +0000 |
|---|---|---|
| committer | Benjamin Kramer <benny.kra@googlemail.com> | 2014-02-02 16:35:43 +0000 |
| commit | 35e6fee3e9a0c7ee1828fbfb31da08298d9881f8 (patch) | |
| tree | fc2e9382bffc4b3baf8cade53ed19c8d92e60b6d /clang | |
| parent | 3a7cc81d52f9b7a6e7e94c9efcd1113f1aeb8c9a (diff) | |
| download | bcm5719-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.cpp | 11 | ||||
| -rw-r--r-- | clang/test/SemaCXX/warn-unused-value.cpp | 2 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/class-template-decl.cpp | 7 |
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}} |

