1 // RUN: %clang_cc1 -std=c++11 -verify %s 2 3 // Check that we deal with cases where the instantiation of a class template 4 // recursively requires the instantiation of the same template. 5 namespace test1 { 6 template<typename T> struct A { 7 struct B { // expected-note {{not complete until the closing '}'}} 8 B b; // expected-error {{has incomplete type 'test1::A<int>::B'}} 9 }; 10 B b; // expected-note {{in instantiation of}} 11 }; 12 A<int> a; // expected-note {{in instantiation of}} 13 } 14 15 namespace test2 { 16 template<typename T> struct A { 17 struct B { 18 struct C {}; 19 char c[1 + C()]; // expected-error {{invalid operands to binary expression}} operator +test2::A20 friend constexpr int operator+(int, C) { return 4; } 21 }; 22 B b; // expected-note {{in instantiation of}} 23 }; 24 A<int> a; // expected-note {{in instantiation of}} 25 } 26 27 namespace test3 { 28 // PR12317 29 template<typename T> struct A { 30 struct B { 31 enum { Val = 1 }; 32 char c[1 + Val]; // ok 33 }; 34 B b; 35 }; 36 A<int> a; 37 } 38 39 namespace test4 { 40 template<typename T> struct M { typedef int type; }; 41 template<typename T> struct A { 42 struct B { // expected-note {{not complete until the closing '}'}} 43 int k[typename A<typename M<T>::type>::B().k[0] + 1]; // expected-error {{incomplete type}} 44 }; 45 B b; // expected-note {{in instantiation of}} 46 }; 47 A<int> a; // expected-note {{in instantiation of}} 48 } 49 50 // FIXME: PR12298: Recursive constexpr function template instantiation leads to 51 // stack overflow. 52 #if 0 53 namespace test5 { 54 template<typename T> struct A { 55 constexpr T f(T k) { return g(k); } 56 constexpr T g(T k) { 57 return k ? f(k-1)+1 : 0; 58 } 59 }; 60 // This should be accepted. 61 constexpr int x = A<int>().f(5); 62 } 63 64 namespace test6 { 65 template<typename T> constexpr T f(T); 66 template<typename T> constexpr T g(T t) { 67 typedef int arr[f(T())]; 68 return t; 69 } 70 template<typename T> constexpr T f(T t) { 71 typedef int arr[g(T())]; 72 return t; 73 } 74 // This should be ill-formed. 75 int n = f(0); 76 } 77 78 namespace test7 { 79 template<typename T> constexpr T g(T t) { 80 return t; 81 } 82 template<typename T> constexpr T f(T t) { 83 typedef int arr[g(T())]; 84 return t; 85 } 86 // This should be accepted. 87 int n = f(0); 88 } 89 #endif 90