________________________________________
From: Gao, Yunzhong
Sent: Wednesday, March 13, 2013 11:51 PM
To: Douglas Gregor
Cc: [email protected]
Subject: RE: [PATCH] Adding a diagnostic for member templates inside a local 
class

Hi Douglas,
Thank you for review.
I am attaching an updated patch with the following changes:

  1. The diagnostic is moved from lib/Parse to lib/SemaTemplate;
  2. Added a new test to test/SemaTemplate instead of test/Parser;
  3. In test/SemaTemplate/instantiate-exception-spec-cxx11.cpp, moved the class 
definition outside of the
      function body to avoid triggering the new diagnostic.
      I did experiment with adding an expected-error annotation there, but it 
seems that delaying the diagnostic
      from Parser to Sema triggers quite a few more error messages, e.g.,
          Line 52: use of undeclared identifier 'f'
          Line 54: no member named 'f' in 'S'
      I think adding more expected-error annotations would unnecessarily 
complicate the existing test. The
      proposed new test checks both function and class templates.

Could you review?
- Gao.

________________________________________
From: Douglas Gregor [[email protected]]
Sent: Wednesday, March 13, 2013 4:13 PM
To: Gao, Yunzhong
Cc: [email protected]
Subject: Re: [PATCH] Adding a diagnostic for member templates inside a local 
class

On Mar 13, 2013, at 12:55 PM, "Gao, Yunzhong" <[email protected]> wrote:

> 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.

Generally, this looks good. However, I'd like to see it diagnosed in Sema, 
rather than in the parser, which we do for static data members and friends in 
local classes.

        - Doug



Index: test/SemaTemplate/member-template-local-class.cpp
===================================================================
--- test/SemaTemplate/member-template-local-class.cpp	(revision 0)
+++ test/SemaTemplate/member-template-local-class.cpp	(revision 0)
@@ -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	(revision 176911)
+++ test/SemaTemplate/instantiate-exception-spec-cxx11.cpp	(working copy)
@@ -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	(revision 176911)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -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	(revision 176911)
+++ lib/Sema/SemaTemplate.cpp	(working copy)
@@ -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;
 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to