1 | // RUN: %clang_cc1 -std=c++1z -verify -pedantic-errors %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}} |
20 | 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 | // PR12298: Recursive constexpr function template instantiation leads to |
51 | // stack overflow. |
52 | namespace test5 { |
53 | template<typename T> struct A { |
54 | constexpr T f(T k) { return g(k); } |
55 | constexpr T g(T k) { |
56 | return k ? f(k-1)+1 : 0; |
57 | } |
58 | }; |
59 | constexpr int x = A<int>().f(5); // ok |
60 | } |
61 | |
62 | namespace test6 { |
63 | template<typename T> constexpr T f(T); |
64 | template<typename T> constexpr T g(T t) { |
65 | typedef int arr[f(T())]; // expected-error {{variable length array}} |
66 | return t; |
67 | } |
68 | template<typename T> constexpr T f(T t) { |
69 | typedef int arr[g(T())]; // expected-error {{zero size array}} expected-note {{instantiation of}} |
70 | return t; |
71 | } |
72 | int n = f(0); // expected-note 2{{instantiation of}} |
73 | } |
74 | |
75 | namespace test7 { |
76 | template<typename T> constexpr T g(T t) { |
77 | return t; |
78 | } |
79 | template<typename T> constexpr T f(T t) { |
80 | typedef int arr[g(T() + 1)]; |
81 | return t; |
82 | } |
83 | int n = f(0); |
84 | } |
85 | |
86 | namespace test8 { |
87 | template<typename T> struct A { |
88 | int n = A{}.n; // expected-error {{default member initializer for 'n' uses itself}} expected-note {{instantiation of default member init}} |
89 | }; |
90 | A<int> ai = {}; // expected-note {{instantiation of default member init}} |
91 | } |
92 | |
93 | namespace test9 { |
94 | template<typename T> struct A { enum class B; }; |
95 | // FIXME: It'd be nice to give the "it has not yet been instantiated" diagnostic here. |
96 | template<typename T> enum class A<T>::B { k = A<T>::B::k2, k2 = k }; // expected-error {{no member named 'k2'}} |
97 | auto k = A<int>::B::k; // expected-note {{in instantiation of}} |
98 | } |
99 | |
100 | namespace test10 { |
101 | template<typename T> struct A { |
102 | void f() noexcept(noexcept(f())); // expected-error {{exception specification of 'f' uses itself}} expected-note {{instantiation of}} |
103 | }; |
104 | bool b = noexcept(A<int>().f()); // expected-note {{instantiation of}} |
105 | } |
106 | |
107 | namespace test11 { |
108 | template<typename T> const int var = var<T>; |
109 | int k = var<int>; |
110 | |
111 | template<typename T> struct X { |
112 | static const int k = X<T>::k; |
113 | }; |
114 | template<typename T> const int X<T>::k; |
115 | int q = X<int>::k; |
116 | |
117 | template<typename T> struct Y { |
118 | static const int k; |
119 | }; |
120 | template<typename T> const int Y<T>::k = Y<T>::k; |
121 | int r = Y<int>::k; |
122 | } |
123 | |
124 | namespace test12 { |
125 | template<typename T> int f(T t, int = f(T())) {} // expected-error {{recursive evaluation of default argument}} expected-note {{instantiation of}} |
126 | struct X {}; |
127 | int q = f(X()); // expected-note {{instantiation of}} |
128 | } |
129 | |
130 | namespace test13 { |
131 | struct A { |
132 | // Cycle via type of non-type template parameter. |
133 | template<typename T, typename T::template W<T>::type U = 0> struct W { using type = int; }; |
134 | // Cycle via default template argument. |
135 | template<typename T, typename U = typename T::template X<T>> struct X {}; |
136 | template<typename T, int U = T::template Y<T>::value> struct Y { static const int value = 0; }; |
137 | template<typename T, template<typename> typename U = T::template Z<T>::template nested> struct Z { template<typename> struct nested; }; |
138 | }; |
139 | template<typename T> struct Wrap { |
140 | template<typename U> struct W : A::W<T> {}; |
141 | template<typename U> struct X : A::X<T> {}; |
142 | template<typename U> struct Y : A::Y<T> {}; |
143 | template<typename U> struct Z : A::Z<T> {}; |
144 | }; |
145 | struct B { |
146 | template<typename U> struct W { using type = int; }; |
147 | template<typename U> struct X {}; |
148 | template<typename U> struct Y { static const int value = 0; }; |
149 | template<typename U> struct Z { template<typename> struct nested; }; |
150 | }; |
151 | |
152 | A::W<B> awb; |
153 | A::X<B> axb; |
154 | A::Y<B> ayb; |
155 | A::Z<B> azb; |
156 | |
157 | A::W<Wrap<Wrap<B>>> awwwb; |
158 | A::X<Wrap<Wrap<B>>> axwwb; |
159 | A::Y<Wrap<Wrap<B>>> aywwb; |
160 | A::Z<Wrap<Wrap<B>>> azwwb; |
161 | |
162 | // FIXME: These tests cause us to use too much stack and crash on a self-hosted debug build. |
163 | // FIXME: Check for recursion here and give a better diagnostic. |
164 | #if 0 |
165 | A::W<A> awa; |
166 | A::X<A> axa; |
167 | A::Y<A> aya; |
168 | A::Z<A> aza; |
169 | #endif |
170 | } |
171 | |