1 // RUN: %clang_cc1 -std=c++1z -verify -pedantic-errors %s
3 // Check that we deal with cases where the instantiation of a class template
4 // recursively requires the instantiation of the same template.
6 template<typename T
> struct A
{
7 struct B
{ // expected-note {{not complete until the closing '}'}}
8 B b
; // expected-error {{has incomplete type 'B'}}
10 B b
; // expected-note {{in instantiation of}}
12 A
<int> a
; // expected-note {{in instantiation of}}
16 template<typename T
> struct A
{
19 char c
[1 + C()]; // expected-error {{invalid operands to binary expression}}
20 friend constexpr int operator+(int, C
) { return 4; }
22 B b
; // expected-note {{in instantiation of}}
24 A
<int> a
; // expected-note {{in instantiation of}}
29 template<typename T
> struct A
{
32 char c
[1 + Val
]; // ok
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}}
45 B b
; // expected-note {{in instantiation of}}
47 A
<int> a
; // expected-note {{in instantiation of}}
50 // PR12298: Recursive constexpr function template instantiation leads to
53 template<typename T
> struct A
{
54 constexpr T
f(T k
) { return g(k
); }
56 return k
? f(k
-1)+1 : 0;
59 constexpr int x
= A
<int>().f(5); // ok
63 template<typename T
> constexpr T
f(T
);
64 template<typename T
> constexpr T
g(T t
) {
65 // FIXME: It'd be nice to say that the function is currently being defined, rather than being undefined.
66 typedef int arr
[f(T())]; // expected-error {{variable length array}} expected-note {{undefined function 'f<int>'}}
69 template<typename T
> constexpr T
f(T t
) { // expected-note {{declared here}}
70 typedef int arr
[g(T())]; // expected-error {{zero size array}} expected-note {{instantiation of}}
73 int n
= f(0); // expected-note 2{{instantiation of}}
77 template<typename T
> constexpr T
g(T t
) {
80 template<typename T
> constexpr T
f(T t
) {
81 typedef int arr
[g(T() + 1)];
88 template<typename T
> struct A
{
89 int n
= A
{}.n
; // expected-error {{default member initializer for 'n' uses itself}} expected-note {{instantiation of default member init}}
91 A
<int> ai
= {}; // expected-note {{instantiation of default member init}}
95 template<typename T
> struct A
{ enum class B
; };
96 // FIXME: It'd be nice to give the "it has not yet been instantiated" diagnostic here.
97 template<typename T
> enum class A
<T
>::B
{ k
= A
<T
>::B::k2
, k2
= k
}; // expected-error {{no member named 'k2'}}
98 auto k
= A
<int>::B::k
; // expected-note {{in instantiation of}}
102 template<typename T
> struct A
{
103 void f() noexcept(noexcept(f())); // expected-error {{exception specification of 'f' uses itself}} expected-note {{instantiation of}}
105 bool b
= noexcept(A
<int>().f()); // expected-note {{instantiation of}}
109 template<typename T
> const int var
= var
<T
>;
112 template<typename T
> struct X
{
113 static const int b
= false;
114 static const int k
= X
<T
>::b
? X
<T
>::k
: 0;
116 template<typename T
> const int X
<T
>::k
;
119 template<typename T
> struct Y
{
122 // OK (but not constant initialization).
123 template<typename T
> const int Y
<T
>::k
= Y
<T
>::k
;
128 template<typename T
> int f(T t
, int = f(T())) {} // expected-error {{recursive evaluation of default argument}} expected-note {{instantiation of}}
130 int q
= f(X()); // expected-note {{instantiation of}}
135 // Cycle via type of non-type template parameter.
136 template<typename T
, typename
T::template W
<T
>::type U
= 0> struct W
{ using type
= int; };
137 // Cycle via default template argument.
138 template<typename T
, typename U
= typename
T::template X
<T
>> struct X
{};
139 template<typename T
, int U
= T::template Y
<T
>::value
> struct Y
{ static const int value
= 0; };
140 template<typename T
, template<typename
> typename U
= T::template Z
<T
>::template nested
> struct Z
{ template<typename
> struct nested
; };
142 template<typename T
> struct Wrap
{
143 template<typename U
> struct W
: A::W
<T
> {};
144 template<typename U
> struct X
: A::X
<T
> {};
145 template<typename U
> struct Y
: A::Y
<T
> {};
146 template<typename U
> struct Z
: A::Z
<T
> {};
149 template<typename U
> struct W
{ using type
= int; };
150 template<typename U
> struct X
{};
151 template<typename U
> struct Y
{ static const int value
= 0; };
152 template<typename U
> struct Z
{ template<typename
> struct nested
; };
160 A::W
<Wrap
<Wrap
<B
>>> awwwb
;
161 A::X
<Wrap
<Wrap
<B
>>> axwwb
;
162 A::Y
<Wrap
<Wrap
<B
>>> aywwb
;
163 A::Z
<Wrap
<Wrap
<B
>>> azwwb
;
165 // FIXME: These tests cause us to use too much stack and crash on a self-hosted debug build.
166 // FIXME: Check for recursion here and give a better diagnostic.