Yep, looks like libcxxabi violates 14.5.2 [temp.mem]/p2. Looks like this violation was introduced back in r184097. Note that trying to compile with GCC gets us a similar error: invalid declaration of member template in local class
CC'ing Howard Hinnant. On Tue, Oct 22, 2013 at 4:36 AM, İsmail Dönmez <[email protected]> wrote: > 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
