<div dir="ltr">This breaks libc++abi:<div><br>[   52s] + clang++ -c -g -O3 -fPIC -std=c++11 -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 -Wsign-conversion -Wshadow -Wconversion -Wunused-variable -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter -Wnewline-eof -I../include ../src/cxa_demangle.cpp<br>

[   53s] ../src/cxa_demangle.cpp:4624:9: error: templates cannot be declared inside of a local class<br>[   53s]         template <size_t N><br>[   53s]         ^~~~~~~~~~~~~~~~~~~<br>[   53s] ../src/cxa_demangle.cpp:4631:8: error: no matching constructor for initialization of 'Db'<br>

[   53s]     Db db(a);<br>[   53s]        ^  ~<br>[   53s] ../src/cxa_demangle.cpp:4609:12: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'arena<bs>' to 'Db' for 1st argument<br>

[   53s]     struct Db<br>[   53s]            ^<br>[   53s] ../src/cxa_demangle.cpp:4609:12: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'arena<bs>' to 'const Db' for 1st argument<br>

[   53s]     struct Db<br>[   53s]            ^<br>[   53s] ../src/cxa_demangle.cpp:4609:12: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided</div></div>
<div class="gmail_extra">
<br><br><div class="gmail_quote">On Tue, Oct 22, 2013 at 7:14 AM, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Author: majnemer<br>
Date: Mon Oct 21 23:14:18 2013<br>
New Revision: 193144<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=193144&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=193144&view=rev</a><br>
Log:<br>
Sema: Do not allow template declarations inside local classes<br>
<br>
Summary:<br>
Enforce the rule in C++11 [temp.mem]p2 that local classes cannot have<br>
member templates.<br>
<br>
This fixes PR16947.<br>
<br>
N.B.  C++14 has slightly different wording to afford generic lambdas<br>
declared inside of functions.<br>
<br>
Fun fact:  Some formulations of local classes with member templates<br>
would cause clang to crash during Itanium mangling, such as the<br>
following:<br>
<br>
void outer_mem() {<br>
  struct Inner {<br>
    template <typename = void><br>
    struct InnerTemplateClass {<br>
      static void itc_mem() {}<br>
    };<br>
  };<br>
  Inner::InnerTemplateClass<>::itc_mem();<br>
}<br>
<br>
Reviewers: eli.friedman, rsmith, doug.gregor, faisalv<br>
<br>
Reviewed By: doug.gregor<br>
<br>
CC: cfe-commits, ygao<br>
<br>
Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D1866" target="_blank">http://llvm-reviews.chandlerc.com/D1866</a><br>
<br>
Added:<br>
    cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp<br>
Removed:<br>
    cfe/trunk/test/PCH/cxx-local-templates.cpp<br>
    cfe/trunk/test/PCH/cxx1y-local-templates.cpp<br>
    cfe/trunk/test/SemaTemplate/local-member-templates.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
    cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp<br>
    cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=193144&r1=193143&r2=193144&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=193144&r1=193143&r2=193144&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 21 23:14:18 2013<br>
@@ -2835,6 +2835,8 @@ def warn_template_export_unsupported : W<br>
   "exported templates are unsupported">;<br>
 def err_template_outside_namespace_or_class_scope : Error<<br>
   "templates can only be declared in namespace or class scope">;<br>
+def err_template_inside_local_class : Error<<br>
+  "templates cannot be declared inside of a local class">;<br>
 def err_template_linkage : Error<"templates must have C++ linkage">;<br>
 def err_template_typedef : Error<"a typedef cannot be a template">;<br>
 def err_template_unnamed_class : Error<<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=193144&r1=193143&r2=193144&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=193144&r1=193143&r2=193144&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Oct 21 23:14:18 2013<br>
@@ -5459,8 +5459,20 @@ Sema::CheckTemplateDeclScope(Scope *S, T<br>
   while (Ctx && isa<LinkageSpecDecl>(Ctx))<br>
     Ctx = Ctx->getParent();<br>
<br>
-  if (Ctx && (Ctx->isFileContext() || Ctx->isRecord()))<br>
-    return false;<br>
+  if (Ctx) {<br>
+    if (Ctx->isFileContext())<br>
+      return false;<br>
+    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Ctx)) {<br>
+      // C++ [temp.mem]p2:<br>
+      //   A local class shall not have member templates.<br>
+      if (RD->isLocalClass())<br>
+        return Diag(TemplateParams->getTemplateLoc(),<br>
+                    diag::err_template_inside_local_class)<br>
+          << TemplateParams->getSourceRange();<br>
+      else<br>
+        return false;<br>
+    }<br>
+  }<br>
<br>
   return Diag(TemplateParams->getTemplateLoc(),<br>
               diag::err_template_outside_namespace_or_class_scope)<br>
<br>
Added: cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp?rev=193144&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp?rev=193144&view=auto</a><br>


==============================================================================<br>
--- cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp (added)<br>
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp Mon Oct 21 23:14:18 2013<br>
@@ -0,0 +1,12 @@<br>
+// RUN: %clang_cc1 -fsyntax-only -verify %s<br>
+<br>
+template <typename><br>
+void quux();<br>
+<br>
+void fun() {<br>
+  struct foo {<br>
+    template <typename> struct bar {};  // expected-error{{templates cannot be declared inside of a local class}}<br>
+    template <typename> void baz() {}   // expected-error{{templates cannot be declared inside of a local class}}<br>
+    template <typename> void qux();     // expected-error{{templates cannot be declared inside of a local class}}<br>
+  };<br>
+}<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp?rev=193144&r1=193143&r2=193144&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp?rev=193144&r1=193143&r2=193144&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp Mon Oct 21 23:14:18 2013<br>
@@ -75,16 +75,6 @@ inline void OmittingCode(float x) {<br>
 }<br>
 void CallOmittingCode() { OmittingCode(1); }<br>
<br>
-// CHECK: @_ZZ25LocalTemplateFunctionTestdEN5Local3fooIdEET_S1_<br>
-int LocalTemplateFunctionTest(double d) {<br>
-  struct Local {<br>
-    template<class T> T foo(T t) {<br>
-      return t;<br>
-    }<br>
-  };<br>
-  return Local().foo(d);<br>
-}<br>
-<br>
 // CHECK: @_ZZ15LocalAnonStructvENUt0_1gEv<br>
 inline void LocalAnonStruct() {<br>
   if (0) {<br>
<br>
Removed: cfe/trunk/test/PCH/cxx-local-templates.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-local-templates.cpp?rev=193143&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-local-templates.cpp?rev=193143&view=auto</a><br>


==============================================================================<br>
--- cfe/trunk/test/PCH/cxx-local-templates.cpp (original)<br>
+++ cfe/trunk/test/PCH/cxx-local-templates.cpp (removed)<br>
@@ -1,55 +0,0 @@<br>
-// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11<br>
-// RUN: %clang_cc1 -ast-print -pedantic-errors -std=c++11 -include-pch %t-cxx11  %s | FileCheck -check-prefix=CHECK-PRINT %s<br>
-<br>
-#ifndef HEADER_INCLUDED<br>
-<br>
-#define HEADER_INCLUDED<br>
-<br>
-int nontemplate_test(double d) {<br>
-  struct Local {<br>
-    template<class T> T foo(T t) {<br>
-      return t;<br>
-    }<br>
-  };<br>
-  return Local{}.foo(d);<br>
-}<br>
-<br>
-template<class U><br>
-U template_test(U d) {<br>
-  struct Local {<br>
-    template<class T> T foo(T t) {<br>
-      return t;<br>
-    }<br>
-  };<br>
-  return Local{}.foo(d);<br>
-}<br>
-<br>
-int nested_local() {<br>
-  struct Inner1 {<br>
-    int inner1_foo(char c) {<br>
-      struct Inner2 {<br>
-        template<class T> T inner2_foo(T t) {<br>
-          return t;<br>
-        }<br>
-      };<br>
-      return Inner2{}.inner2_foo(3.14);<br>
-    }<br>
-  };<br>
-  return Inner1{}.inner1_foo('a');<br>
-}<br>
-<br>
-#else<br>
-<br>
-// CHECK-PRINT: U template_test<br>
-<br>
-// CHECK-PRINT: int nontemplate_test(double)<br>
-<br>
-int nontemplate_test(double);<br>
-<br>
-template double template_test(double);<br>
-int test2(int y) {<br>
-  return nontemplate_test(y) + template_test(y);<br>
-}<br>
-<br>
-<br>
-#endif<br>
<br>
Removed: cfe/trunk/test/PCH/cxx1y-local-templates.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx1y-local-templates.cpp?rev=193143&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx1y-local-templates.cpp?rev=193143&view=auto</a><br>


==============================================================================<br>
--- cfe/trunk/test/PCH/cxx1y-local-templates.cpp (original)<br>
+++ cfe/trunk/test/PCH/cxx1y-local-templates.cpp (removed)<br>
@@ -1,58 +0,0 @@<br>
-// RUN: %clang_cc1 -pedantic-errors -std=c++1y -emit-pch %s -o %t-cxx1y<br>
-// RUN: %clang_cc1 -ast-print -pedantic-errors -std=c++1y -include-pch %t-cxx1y  %s | FileCheck -check-prefix=CHECK-PRINT %s<br>
-<br>
-#ifndef HEADER_INCLUDED<br>
-<br>
-#define HEADER_INCLUDED<br>
-<br>
-auto nested_local_call_all() {<br>
-  struct Inner1 {<br>
-    auto inner1_foo(char c) {<br>
-      struct Inner2 {<br>
-        template<class T> T inner2_foo(T t) {<br>
-          return t;<br>
-        }<br>
-      };<br>
-      return Inner2{};<br>
-    }<br>
-  };<br>
-  return Inner1{}.inner1_foo('a').inner2_foo(4);<br>
-}<br>
-<br>
-<br>
-auto nested_local() {<br>
-  struct Inner1 {<br>
-    auto inner1_foo(char c) {<br>
-      struct Inner2 {<br>
-        template<class T> T inner2_foo(T t) {<br>
-          return t;<br>
-        }<br>
-      };<br>
-      return Inner2{};<br>
-    }<br>
-  };<br>
-  return Inner1{};<br>
-}<br>
-<br>
-<br>
-int test() {<br>
-  auto A = nested_local_call_all();<br>
-  auto B = nested_local();<br>
-  auto C = B.inner1_foo('a');<br>
-  C.inner2_foo(3.14);<br>
-<br>
-}<br>
-<br>
-<br>
-#else<br>
-<br>
-// CHECK-PRINT: int nested_local_call_all<br>
-// CHECK-PRINT: nested_local<br>
-auto nested_local_call_all();<br>
-<br>
-int test(int y) {<br>
-  return nested_local_call_all();<br>
-}<br>
-<br>
-<br>
-#endif<br>
<br>
Modified: cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp?rev=193144&r1=193143&r2=193144&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp?rev=193144&r1=193143&r2=193144&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp (original)<br>
+++ cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp Mon Oct 21 23:14:18 2013<br>
@@ -44,13 +44,14 @@ namespace dr1330_example {<br>
     A<int>().f(42);<br>
   }<br>
<br>
+  struct S {<br>
+    template<typename T><br>
+    static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \<br>
+    // expected-note {{instantiation of exception spec}}<br>
+    typedef decltype(f<S>()) X;<br>
+  };<br>
+<br>
   int test2() {<br>
-    struct S {<br>
-      template<typename T><br>
-      static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \<br>
-      // expected-note {{instantiation of exception spec}}<br>
-      typedef decltype(f<S>()) X;<br>
-    };<br>
     S().f<S>(); // ok<br>
     S().f<int>(); // expected-note {{instantiation of exception spec}}<br>
   }<br>
<br>
Removed: cfe/trunk/test/SemaTemplate/local-member-templates.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/local-member-templates.cpp?rev=193143&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/local-member-templates.cpp?rev=193143&view=auto</a><br>


==============================================================================<br>
--- cfe/trunk/test/SemaTemplate/local-member-templates.cpp (original)<br>
+++ cfe/trunk/test/SemaTemplate/local-member-templates.cpp (removed)<br>
@@ -1,99 +0,0 @@<br>
-// RUN: %clang_cc1 -std=c++1y -verify %s<br>
-// RUN: %clang_cc1 -std=c++1y -verify %s -fdelayed-template-parsing<br>
-<br>
-namespace nested_local_templates_1 {<br>
-<br>
-template <class T> struct Outer {<br>
-  template <class U> int outer_mem(T t, U u) {<br>
-    struct Inner {<br>
-      template <class V> int inner_mem(T t, U u, V v) {<br>
-        struct InnerInner {<br>
-          template <class W> int inner_inner_mem(W w, T t, U u, V v) {<br>
-            return 0;<br>
-          }<br>
-        };<br>
-        InnerInner().inner_inner_mem("abc", t, u, v);<br>
-        return 0;<br>
-      }<br>
-    };<br>
-    Inner i;<br>
-    i.inner_mem(t, u, 3.14);<br>
-    return 0;<br>
-  }<br>
-<br>
-  template <class U> int outer_mem(T t, U *u);<br>
-};<br>
-<br>
-template int Outer<int>::outer_mem(int, char);<br>
-<br>
-template <class T> template <class U> int Outer<T>::outer_mem(T t, U *u) {<br>
-  struct Inner {<br>
-    template <class V><br>
-    int inner_mem(T t, U u, V v) { //expected-note{{candidate function}}<br>
-      struct InnerInner {<br>
-        template <class W> int inner_inner_mem(W w, T t, U u, V v) { return 0; }<br>
-      };<br>
-      InnerInner().inner_inner_mem("abc", t, u, v);<br>
-      return 0;<br>
-    }<br>
-  };<br>
-  Inner i;<br>
-  i.inner_mem(t, U{}, i);<br>
-  i.inner_mem(t, u, 3.14); //expected-error{{no matching member function for call to 'inner}}<br>
-  return 0;<br>
-}<br>
-<br>
-template int Outer<int>::outer_mem(int, char *); //expected-note{{in instantiation of function}}<br>
-<br>
-} // end ns<br>
-<br>
-namespace nested_local_templates_2 {<br>
-<br>
-template <class T> struct Outer {<br>
-  template <class U> void outer_mem(T t, U u) {<br>
-    struct Inner {<br>
-      template <class V> struct InnerTemplateClass {<br>
-        template <class W><br>
-        void itc_mem(T t, U u, V v, W w) { //expected-note{{candidate function}}<br>
-          struct InnerInnerInner {<br>
-            template <class X> void iii_mem(X x) {}<br>
-          };<br>
-          InnerInnerInner i;<br>
-          i.iii_mem("abc");<br>
-        }<br>
-      };<br>
-    };<br>
-    Inner i;<br>
-    typename Inner::template InnerTemplateClass<Inner> ii;<br>
-    ii.itc_mem(t, u, i, "jim");<br>
-    ii.itc_mem(t, u, 0, "abd"); //expected-error{{no matching member function}}<br>
-  }<br>
-};<br>
-<br>
-template void<br>
-Outer<int>::outer_mem(int, char); //expected-note{{in instantiation of}}<br>
-<br>
-}<br>
-<br>
-namespace more_nested_local_templates {<br>
-<br>
-int test() {<br>
-  struct Local {<br>
-    template<class U> void foo(U u) {<br>
-      struct Inner {<br>
-        template<class A><br>
-        auto operator()(A a, U u2) -> U {<br>
-          return u2;<br>
-        };<br>
-      };<br>
-      Inner GL;<br>
-      GL('a', u );<br>
-      GL(3.14, u );<br>
-    }<br>
-  };<br>
-  Local l;<br>
-  l.foo("nmabc");<br>
-  return 0;<br>
-}<br>
-int t = test();<br>
-}<br>
\ No newline at end of file<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>