1564f4c5664f552becbd05407611a92754c40e641Richard Smith// RUN: %clang_cc1 -std=c++11 -verify %s 2564f4c5664f552becbd05407611a92754c40e641Richard Smith 3564f4c5664f552becbd05407611a92754c40e641Richard Smith// Check that we deal with cases where the instantiation of a class template 4564f4c5664f552becbd05407611a92754c40e641Richard Smith// recursively requires the instantiation of the same template. 5564f4c5664f552becbd05407611a92754c40e641Richard Smithnamespace test1 { 6564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> struct A { 7564f4c5664f552becbd05407611a92754c40e641Richard Smith struct B { // expected-note {{not complete until the closing '}'}} 8564f4c5664f552becbd05407611a92754c40e641Richard Smith B b; // expected-error {{has incomplete type 'test1::A<int>::B'}} 9564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 10564f4c5664f552becbd05407611a92754c40e641Richard Smith B b; // expected-note {{in instantiation of}} 11564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 12564f4c5664f552becbd05407611a92754c40e641Richard Smith A<int> a; // expected-note {{in instantiation of}} 13564f4c5664f552becbd05407611a92754c40e641Richard Smith} 14564f4c5664f552becbd05407611a92754c40e641Richard Smith 15564f4c5664f552becbd05407611a92754c40e641Richard Smithnamespace test2 { 16564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> struct A { 17564f4c5664f552becbd05407611a92754c40e641Richard Smith struct B { 18564f4c5664f552becbd05407611a92754c40e641Richard Smith struct C {}; 19564f4c5664f552becbd05407611a92754c40e641Richard Smith char c[1 + C()]; // expected-error {{invalid operands to binary expression}} 20564f4c5664f552becbd05407611a92754c40e641Richard Smith friend constexpr int operator+(int, C) { return 4; } 21564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 22564f4c5664f552becbd05407611a92754c40e641Richard Smith B b; // expected-note {{in instantiation of}} 23564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 24564f4c5664f552becbd05407611a92754c40e641Richard Smith A<int> a; // expected-note {{in instantiation of}} 25564f4c5664f552becbd05407611a92754c40e641Richard Smith} 26564f4c5664f552becbd05407611a92754c40e641Richard Smith 27564f4c5664f552becbd05407611a92754c40e641Richard Smithnamespace test3 { 28564f4c5664f552becbd05407611a92754c40e641Richard Smith // PR12317 29564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> struct A { 30564f4c5664f552becbd05407611a92754c40e641Richard Smith struct B { 31564f4c5664f552becbd05407611a92754c40e641Richard Smith enum { Val = 1 }; 32564f4c5664f552becbd05407611a92754c40e641Richard Smith char c[1 + Val]; // ok 33564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 34564f4c5664f552becbd05407611a92754c40e641Richard Smith B b; 35564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 36564f4c5664f552becbd05407611a92754c40e641Richard Smith A<int> a; 37564f4c5664f552becbd05407611a92754c40e641Richard Smith} 38564f4c5664f552becbd05407611a92754c40e641Richard Smith 39564f4c5664f552becbd05407611a92754c40e641Richard Smithnamespace test4 { 40564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> struct M { typedef int type; }; 41564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> struct A { 42564f4c5664f552becbd05407611a92754c40e641Richard Smith struct B { // expected-note {{not complete until the closing '}'}} 43564f4c5664f552becbd05407611a92754c40e641Richard Smith int k[typename A<typename M<T>::type>::B().k[0] + 1]; // expected-error {{incomplete type}} 44564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 45564f4c5664f552becbd05407611a92754c40e641Richard Smith B b; // expected-note {{in instantiation of}} 46564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 47564f4c5664f552becbd05407611a92754c40e641Richard Smith A<int> a; // expected-note {{in instantiation of}} 48564f4c5664f552becbd05407611a92754c40e641Richard Smith} 49564f4c5664f552becbd05407611a92754c40e641Richard Smith 50564f4c5664f552becbd05407611a92754c40e641Richard Smith// FIXME: PR12298: Recursive constexpr function template instantiation leads to 51564f4c5664f552becbd05407611a92754c40e641Richard Smith// stack overflow. 52564f4c5664f552becbd05407611a92754c40e641Richard Smith#if 0 53564f4c5664f552becbd05407611a92754c40e641Richard Smithnamespace test5 { 54564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> struct A { 55564f4c5664f552becbd05407611a92754c40e641Richard Smith constexpr T f(T k) { return g(k); } 56564f4c5664f552becbd05407611a92754c40e641Richard Smith constexpr T g(T k) { 57564f4c5664f552becbd05407611a92754c40e641Richard Smith return k ? f(k-1)+1 : 0; 58564f4c5664f552becbd05407611a92754c40e641Richard Smith } 59564f4c5664f552becbd05407611a92754c40e641Richard Smith }; 60564f4c5664f552becbd05407611a92754c40e641Richard Smith // This should be accepted. 61564f4c5664f552becbd05407611a92754c40e641Richard Smith constexpr int x = A<int>().f(5); 62564f4c5664f552becbd05407611a92754c40e641Richard Smith} 63564f4c5664f552becbd05407611a92754c40e641Richard Smith 64564f4c5664f552becbd05407611a92754c40e641Richard Smithnamespace test6 { 65564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> constexpr T f(T); 66564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> constexpr T g(T t) { 67564f4c5664f552becbd05407611a92754c40e641Richard Smith typedef int arr[f(T())]; 68564f4c5664f552becbd05407611a92754c40e641Richard Smith return t; 69564f4c5664f552becbd05407611a92754c40e641Richard Smith } 70564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> constexpr T f(T t) { 71564f4c5664f552becbd05407611a92754c40e641Richard Smith typedef int arr[g(T())]; 72564f4c5664f552becbd05407611a92754c40e641Richard Smith return t; 73564f4c5664f552becbd05407611a92754c40e641Richard Smith } 74564f4c5664f552becbd05407611a92754c40e641Richard Smith // This should be ill-formed. 75564f4c5664f552becbd05407611a92754c40e641Richard Smith int n = f(0); 76564f4c5664f552becbd05407611a92754c40e641Richard Smith} 77564f4c5664f552becbd05407611a92754c40e641Richard Smith 78564f4c5664f552becbd05407611a92754c40e641Richard Smithnamespace test7 { 79564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> constexpr T g(T t) { 80564f4c5664f552becbd05407611a92754c40e641Richard Smith return t; 81564f4c5664f552becbd05407611a92754c40e641Richard Smith } 82564f4c5664f552becbd05407611a92754c40e641Richard Smith template<typename T> constexpr T f(T t) { 83564f4c5664f552becbd05407611a92754c40e641Richard Smith typedef int arr[g(T())]; 84564f4c5664f552becbd05407611a92754c40e641Richard Smith return t; 85564f4c5664f552becbd05407611a92754c40e641Richard Smith } 86564f4c5664f552becbd05407611a92754c40e641Richard Smith // This should be accepted. 87564f4c5664f552becbd05407611a92754c40e641Richard Smith int n = f(0); 88564f4c5664f552becbd05407611a92754c40e641Richard Smith} 89564f4c5664f552becbd05407611a92754c40e641Richard Smith#endif 90