summaryrefslogtreecommitdiff
path: root/test/SemaTemplate
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-10-22 04:14:18 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-10-22 04:14:18 +0000
commit588a51a471b4cb23613e8183e05d2d193d2ab813 (patch)
tree6694aba70d5968f2b4e245f4fa0b2bfd64f0c312 /test/SemaTemplate
parent2cfbf0552f90c7ef42975ca1b9064888550ca2ee (diff)
downloadclang-588a51a471b4cb23613e8183e05d2d193d2ab813.tar.gz
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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193144 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaTemplate')
-rw-r--r--test/SemaTemplate/instantiate-exception-spec-cxx11.cpp13
-rw-r--r--test/SemaTemplate/local-member-templates.cpp99
2 files changed, 7 insertions, 105 deletions
diff --git a/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp b/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
index 97bf00303b..5f43ea2c27 100644
--- a/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
+++ b/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
@@ -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}}
}
diff --git a/test/SemaTemplate/local-member-templates.cpp b/test/SemaTemplate/local-member-templates.cpp
deleted file mode 100644
index 847d483a00..0000000000
--- a/test/SemaTemplate/local-member-templates.cpp
+++ /dev/null
@@ -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