This breaks libc++abi: [ 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 [ 53s] ../src/cxa_demangle.cpp:4624:9: error: templates cannot be declared inside of a local class [ 53s] template <size_t N> [ 53s] ^~~~~~~~~~~~~~~~~~~ [ 53s] ../src/cxa_demangle.cpp:4631:8: error: no matching constructor for initialization of 'Db' [ 53s] Db db(a); [ 53s] ^ ~ [ 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 [ 53s] struct Db [ 53s] ^ [ 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 [ 53s] struct Db [ 53s] ^ [ 53s] ../src/cxa_demangle.cpp:4609:12: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
On Tue, Oct 22, 2013 at 7:14 AM, David Majnemer <[email protected]>wrote: > Author: majnemer > Date: Mon Oct 21 23:14:18 2013 > New Revision: 193144 > > URL: http://llvm.org/viewvc/llvm-project?rev=193144&view=rev > Log: > Sema: Do not allow template declarations inside local classes > > Summary: > Enforce the rule in C++11 [temp.mem]p2 that local classes cannot have > member templates. > > This fixes PR16947. > > N.B. C++14 has slightly different wording to afford generic lambdas > declared inside of functions. > > Fun fact: Some formulations of local classes with member templates > would cause clang to crash during Itanium mangling, such as the > following: > > void outer_mem() { > struct Inner { > template <typename = void> > struct InnerTemplateClass { > static void itc_mem() {} > }; > }; > Inner::InnerTemplateClass<>::itc_mem(); > } > > Reviewers: eli.friedman, rsmith, doug.gregor, faisalv > > Reviewed By: doug.gregor > > CC: cfe-commits, ygao > > Differential Revision: http://llvm-reviews.chandlerc.com/D1866 > > Added: > cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp > Removed: > cfe/trunk/test/PCH/cxx-local-templates.cpp > cfe/trunk/test/PCH/cxx1y-local-templates.cpp > cfe/trunk/test/SemaTemplate/local-member-templates.cpp > Modified: > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/lib/Sema/SemaTemplate.cpp > cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp > cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=193144&r1=193143&r2=193144&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 21 > 23:14:18 2013 > @@ -2835,6 +2835,8 @@ def warn_template_export_unsupported : W > "exported templates are unsupported">; > def err_template_outside_namespace_or_class_scope : Error< > "templates can only be declared in namespace or class scope">; > +def err_template_inside_local_class : Error< > + "templates cannot be declared inside of a local class">; > def err_template_linkage : Error<"templates must have C++ linkage">; > def err_template_typedef : Error<"a typedef cannot be a template">; > def err_template_unnamed_class : Error< > > Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=193144&r1=193143&r2=193144&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Oct 21 23:14:18 2013 > @@ -5459,8 +5459,20 @@ Sema::CheckTemplateDeclScope(Scope *S, T > while (Ctx && isa<LinkageSpecDecl>(Ctx)) > Ctx = Ctx->getParent(); > > - if (Ctx && (Ctx->isFileContext() || Ctx->isRecord())) > - return false; > + if (Ctx) { > + if (Ctx->isFileContext()) > + return false; > + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Ctx)) { > + // C++ [temp.mem]p2: > + // A local class shall not have member templates. > + if (RD->isLocalClass()) > + return Diag(TemplateParams->getTemplateLoc(), > + diag::err_template_inside_local_class) > + << TemplateParams->getSourceRange(); > + else > + return false; > + } > + } > > return Diag(TemplateParams->getTemplateLoc(), > diag::err_template_outside_namespace_or_class_scope) > > Added: cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp?rev=193144&view=auto > > ============================================================================== > --- cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp (added) > +++ cfe/trunk/test/CXX/temp/temp.decls/temp.mem/p2.cpp Mon Oct 21 23:14:18 > 2013 > @@ -0,0 +1,12 @@ > +// RUN: %clang_cc1 -fsyntax-only -verify %s > + > +template <typename> > +void quux(); > + > +void fun() { > + struct foo { > + template <typename> struct bar {}; // expected-error{{templates > cannot be declared inside of a local class}} > + template <typename> void baz() {} // expected-error{{templates > cannot be declared inside of a local class}} > + template <typename> void qux(); // expected-error{{templates > cannot be declared inside of a local class}} > + }; > +} > > Modified: cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp?rev=193144&r1=193143&r2=193144&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/mangle-local-class-names.cpp Mon Oct 21 > 23:14:18 2013 > @@ -75,16 +75,6 @@ inline void OmittingCode(float x) { > } > void CallOmittingCode() { OmittingCode(1); } > > -// CHECK: @_ZZ25LocalTemplateFunctionTestdEN5Local3fooIdEET_S1_ > -int LocalTemplateFunctionTest(double d) { > - struct Local { > - template<class T> T foo(T t) { > - return t; > - } > - }; > - return Local().foo(d); > -} > - > // CHECK: @_ZZ15LocalAnonStructvENUt0_1gEv > inline void LocalAnonStruct() { > if (0) { > > Removed: cfe/trunk/test/PCH/cxx-local-templates.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx-local-templates.cpp?rev=193143&view=auto > > ============================================================================== > --- cfe/trunk/test/PCH/cxx-local-templates.cpp (original) > +++ cfe/trunk/test/PCH/cxx-local-templates.cpp (removed) > @@ -1,55 +0,0 @@ > -// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11 > -// RUN: %clang_cc1 -ast-print -pedantic-errors -std=c++11 -include-pch > %t-cxx11 %s | FileCheck -check-prefix=CHECK-PRINT %s > - > -#ifndef HEADER_INCLUDED > - > -#define HEADER_INCLUDED > - > -int nontemplate_test(double d) { > - struct Local { > - template<class T> T foo(T t) { > - return t; > - } > - }; > - return Local{}.foo(d); > -} > - > -template<class U> > -U template_test(U d) { > - struct Local { > - template<class T> T foo(T t) { > - return t; > - } > - }; > - return Local{}.foo(d); > -} > - > -int nested_local() { > - struct Inner1 { > - int inner1_foo(char c) { > - struct Inner2 { > - template<class T> T inner2_foo(T t) { > - return t; > - } > - }; > - return Inner2{}.inner2_foo(3.14); > - } > - }; > - return Inner1{}.inner1_foo('a'); > -} > - > -#else > - > -// CHECK-PRINT: U template_test > - > -// CHECK-PRINT: int nontemplate_test(double) > - > -int nontemplate_test(double); > - > -template double template_test(double); > -int test2(int y) { > - return nontemplate_test(y) + template_test(y); > -} > - > - > -#endif > > Removed: cfe/trunk/test/PCH/cxx1y-local-templates.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx1y-local-templates.cpp?rev=193143&view=auto > > ============================================================================== > --- cfe/trunk/test/PCH/cxx1y-local-templates.cpp (original) > +++ cfe/trunk/test/PCH/cxx1y-local-templates.cpp (removed) > @@ -1,58 +0,0 @@ > -// RUN: %clang_cc1 -pedantic-errors -std=c++1y -emit-pch %s -o %t-cxx1y > -// RUN: %clang_cc1 -ast-print -pedantic-errors -std=c++1y -include-pch > %t-cxx1y %s | FileCheck -check-prefix=CHECK-PRINT %s > - > -#ifndef HEADER_INCLUDED > - > -#define HEADER_INCLUDED > - > -auto nested_local_call_all() { > - struct Inner1 { > - auto inner1_foo(char c) { > - struct Inner2 { > - template<class T> T inner2_foo(T t) { > - return t; > - } > - }; > - return Inner2{}; > - } > - }; > - return Inner1{}.inner1_foo('a').inner2_foo(4); > -} > - > - > -auto nested_local() { > - struct Inner1 { > - auto inner1_foo(char c) { > - struct Inner2 { > - template<class T> T inner2_foo(T t) { > - return t; > - } > - }; > - return Inner2{}; > - } > - }; > - return Inner1{}; > -} > - > - > -int test() { > - auto A = nested_local_call_all(); > - auto B = nested_local(); > - auto C = B.inner1_foo('a'); > - C.inner2_foo(3.14); > - > -} > - > - > -#else > - > -// CHECK-PRINT: int nested_local_call_all > -// CHECK-PRINT: nested_local > -auto nested_local_call_all(); > - > -int test(int y) { > - return nested_local_call_all(); > -} > - > - > -#endif > > Modified: cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp?rev=193144&r1=193143&r2=193144&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp > (original) > +++ cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp Mon > Oct 21 23:14:18 2013 > @@ -44,13 +44,14 @@ namespace dr1330_example { > 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}} > } > > Removed: cfe/trunk/test/SemaTemplate/local-member-templates.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/local-member-templates.cpp?rev=193143&view=auto > > ============================================================================== > --- cfe/trunk/test/SemaTemplate/local-member-templates.cpp (original) > +++ cfe/trunk/test/SemaTemplate/local-member-templates.cpp (removed) > @@ -1,99 +0,0 @@ > -// RUN: %clang_cc1 -std=c++1y -verify %s > -// RUN: %clang_cc1 -std=c++1y -verify %s -fdelayed-template-parsing > - > -namespace nested_local_templates_1 { > - > -template <class T> struct Outer { > - template <class U> int outer_mem(T t, U u) { > - struct Inner { > - template <class V> int inner_mem(T t, U u, V v) { > - struct InnerInner { > - template <class W> int inner_inner_mem(W w, T t, U u, V v) { > - return 0; > - } > - }; > - InnerInner().inner_inner_mem("abc", t, u, v); > - return 0; > - } > - }; > - Inner i; > - i.inner_mem(t, u, 3.14); > - return 0; > - } > - > - template <class U> int outer_mem(T t, U *u); > -}; > - > -template int Outer<int>::outer_mem(int, char); > - > -template <class T> template <class U> int Outer<T>::outer_mem(T t, U *u) { > - struct Inner { > - template <class V> > - int inner_mem(T t, U u, V v) { //expected-note{{candidate function}} > - struct InnerInner { > - template <class W> int inner_inner_mem(W w, T t, U u, V v) { > return 0; } > - }; > - InnerInner().inner_inner_mem("abc", t, u, v); > - return 0; > - } > - }; > - Inner i; > - i.inner_mem(t, U{}, i); > - i.inner_mem(t, u, 3.14); //expected-error{{no matching member function > for call to 'inner}} > - return 0; > -} > - > -template int Outer<int>::outer_mem(int, char *); //expected-note{{in > instantiation of function}} > - > -} // end ns > - > -namespace nested_local_templates_2 { > - > -template <class T> struct Outer { > - template <class U> void outer_mem(T t, U u) { > - struct Inner { > - template <class V> struct InnerTemplateClass { > - template <class W> > - void itc_mem(T t, U u, V v, W w) { //expected-note{{candidate > function}} > - struct InnerInnerInner { > - template <class X> void iii_mem(X x) {} > - }; > - InnerInnerInner i; > - i.iii_mem("abc"); > - } > - }; > - }; > - Inner i; > - typename Inner::template InnerTemplateClass<Inner> ii; > - ii.itc_mem(t, u, i, "jim"); > - ii.itc_mem(t, u, 0, "abd"); //expected-error{{no matching member > function}} > - } > -}; > - > -template void > -Outer<int>::outer_mem(int, char); //expected-note{{in instantiation of}} > - > -} > - > -namespace more_nested_local_templates { > - > -int test() { > - struct Local { > - template<class U> void foo(U u) { > - struct Inner { > - template<class A> > - auto operator()(A a, U u2) -> U { > - return u2; > - }; > - }; > - Inner GL; > - GL('a', u ); > - GL(3.14, u ); > - } > - }; > - Local l; > - l.foo("nmabc"); > - return 0; > -} > -int t = test(); > -} > \ No newline at end of file > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
