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