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