[PATCH] Adding a diagnostic for member templates inside a local class
YunZhong Gao
gaoyunzhong at gmail.com
Mon Mar 25 17:02:06 PDT 2013
Hi doug.gregor,
Currently, clang++ accepts the following codes without any error message.
int test(void)
{
class A {
template<class T> class B
{ T t; };
};
return 0;
}
However, I believe that an error message is required according to the C++03 and C++11.
In particular, section 14.5 clause 2 (of both specs) says "A local class shall not have member templates."
This patch adds a diagnostic for member templates declared inside a local class.
http://llvm-reviews.chandlerc.com/D575
Files:
test/SemaTemplate/member-template-local-class.cpp
test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaTemplate.cpp
Index: test/SemaTemplate/member-template-local-class.cpp
===================================================================
--- test/SemaTemplate/member-template-local-class.cpp
+++ test/SemaTemplate/member-template-local-class.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+int test1(void)
+{
+ class A {
+ template<class T> // expected-error {{member template is not allowed in a local class}}
+ class B
+ {
+ T t;
+ };
+ };
+
+ return 0;
+}
+
+int test2(void)
+{
+ class A {
+ template<class T> // expected-error {{member template is not allowed in a local class}}
+ int B()
+ {
+ return 0;
+ }
+ };
+
+ return 0;
+}
+
Index: test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
===================================================================
--- test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
+++ test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
@@ -44,13 +44,14 @@
A<int>().f(42);
}
+ struct S {
+ template<typename T>
+ static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \
+ // expected-note {{instantiation of exception spec}}
+ typedef decltype(f<S>()) X;
+ };
+
int test2() {
- struct S {
- template<typename T>
- static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \
- // expected-note {{instantiation of exception spec}}
- typedef decltype(f<S>()) X;
- };
S().f<S>(); // ok
S().f<int>(); // expected-note {{instantiation of exception spec}}
}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2655,7 +2655,9 @@
"%select{|template parameter }0redeclaration">;
def note_template_param_different_kind : Note<
"template parameter has a different kind in template argument">;
-
+def err_member_template_in_local_class : Error<
+ "member template is not allowed in a local class">;
+
def err_template_nontype_parm_different_type : Error<
"template non-type parameter has a different type %0 in template "
"%select{|template parameter }1redeclaration">;
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -4908,6 +4908,15 @@
while (Ctx && isa<LinkageSpecDecl>(Ctx))
Ctx = Ctx->getParent();
+ if (Ctx && Ctx->isRecord()) {
+ const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Ctx);
+ if (RD && RD->isLocalClass()) {
+ return Diag(TemplateParams->getTemplateLoc(),
+ diag::err_member_template_in_local_class)
+ << TemplateParams->getSourceRange();
+ }
+ }
+
if (Ctx && (Ctx->isFileContext() || Ctx->isRecord()))
return false;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D575.1.patch
Type: text/x-patch
Size: 2952 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130325/30abd861/attachment.bin>
More information about the cfe-commits
mailing list