[PATCH] Adding a diagnostic for member templates inside a local class
Gao, Yunzhong
Yunzhong.Gao at am.sony.com
Wed Mar 13 12:55:54 PDT 2013
Hi,
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."
The following patch adds a diagnostic for member templates declared inside a local class.
- Gao.
FIles:
A test/Parser/cxx-member-template.cpp
M SemaTemplate/instantiate-exception-spec-cxx11.cpp
M include/clang/Basic/DiagnosticParseKinds.td
M lib/Parse/ParseDeclCXX.cpp
Index: test/Parser/cxx-member-template.cpp
===================================================================
--- test/Parser/cxx-member-template.cpp (revision 0)
+++ test/Parser/cxx-member-template.cpp (revision 0)
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+int test(void)
+{
+ class A {
+ template<class T> class B // expected-error {{member template is not allowed in a local class}}
+ {
+ T t;
+ };
+ };
+
+ return 0;
+}
Index: test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
===================================================================
--- test/SemaTemplate/instantiate-exception-spec-cxx11.cpp (revision 176911)
+++ test/SemaTemplate/instantiate-exception-spec-cxx11.cpp (working copy)
@@ -46,7 +46,7 @@
int test2() {
struct S {
- template<typename T>
+ template<typename T> // expected-error {{member template is not allowed in a local class}}
static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \
// expected-note {{instantiation of exception spec}}
typedef decltype(f<S>()) X;
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td (revision 176911)
+++ include/clang/Basic/DiagnosticParseKinds.td (working copy)
@@ -555,6 +555,8 @@
"definition is meant to be an explicit specialization, add '<>' after the "
"'template' keyword">;
def err_enum_template : Error<"enumeration cannot be a template">;
+def err_member_template_in_local_class : Error<
+ "member template is not allowed in a local class">;
def err_explicit_instantiation_enum : Error<
"enumerations cannot be explicitly instantiated">;
def err_expected_template_parameter : Error<"expected template parameter">;
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp (revision 176911)
+++ lib/Parse/ParseDeclCXX.cpp (working copy)
@@ -13,6 +13,7 @@
#include "clang/Parse/Parser.h"
#include "RAIIObjectsForParser.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Parse/ParseDiagnostic.h"
@@ -1937,6 +1938,13 @@
assert(!TemplateInfo.TemplateParams &&
"Nested template improperly parsed?");
SourceLocation DeclEnd;
+ if (getLangOpts().CPlusPlus && Actions.CurContext->isRecord()) {
+ const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Actions.CurContext);
+ if (RD != NULL && RD->isLocalClass()) {
+ Diag(Tok, diag::err_member_template_in_local_class);
+ }
+ }
+
ParseDeclarationStartingWithTemplate(Declarator::MemberContext, DeclEnd,
AS, AccessAttrs);
return;
More information about the cfe-commits
mailing list