[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