1 // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
3 // C++20 [temp.spec] 13.9/6:
4 // The usual access checking rules do not apply to names in a declaration
5 // of an explicit instantiation or explicit specialization, with the
6 // exception of names appearing in a function body, default argument,
7 // base-clause, member-specification, enumerator-list, or static data member
8 // or variable template initializer.
9 // [Note : In particular, the template arguments and names used in the
10 // function declarator(including parameter types, return types and exception
11 // specifications) may be private types or objects that would normally not be
12 // accessible. — end note]
15 // expected-note@+1 17{{implicitly declared private here}}
16 template <typename T
> class B
{};
17 // expected-note@+1 3{{implicitly declared private here}}
18 static constexpr int num1
= 42;
21 // expected-note@+1 13{{declared protected here}}
23 // expected-note@+1 2{{declared protected here}}
24 static constexpr int num2
= 43;
28 template <typename T
> class D
{};
29 static constexpr int num3
= 44;
37 // expected-error@+1 {{is a private member of}}
38 template <typename T
= A::B
<int>> void func1();
39 template <typename T
= A::C
> void func2();
40 template <typename T
= class A::D
<int>> void func3();
41 // expected-error@+1 {{is a private member of}}
42 template <typename T
> A::B
<int> func4();
43 // expected-error@+1 {{is a private member of}}
44 template <typename T
> A::B
<T
> func5();
45 template <typename T
> class A::C
func6();
46 template <typename T
> class A::D
<int> func7();
47 // expected-error@+1 2{{is a private member of}}
48 template <typename T
> void func8(class A::B
<T
>, int x
= A::num1
);
49 template <typename T
> void func9(A::C
, A::D
<T
>, int = A::num3
);
51 // Specializations inside class declaration
52 template <> void func1
<A::B
<char>>() {}
53 template <> void func2
<class A::D
<char>>() {
54 } template <> void func3
<class A::C
>() {
56 template <> class A::B
<int> func4
<A::B
<char>>() { return {}; } template <> A::B
<A::D
<int>> func5
<A::D
<int>>() {
59 template <> class A::C func6
<A::C
>() { return {}; } template <> A::D
<int> func7
<char>() {
62 template <> void func8
<char>(class A::B
<char>, int) {}
63 template <> void func9
<A::B
<char>>(A::C
, A::D
<A::B
<char>>, int) {}
65 // FIXME: Instantiations inside class declaration.
66 // don't work correctly.
71 template <typename T
> void E::func1() {}
72 template <typename T
> void E::func2() {}
73 template <typename T
> void E::func3() {}
74 // expected-error@+1 {{is a private member of}}
75 template <typename T
> A::B
<int> E::func4() { return {}; }
76 // expected-error@+1 {{is a private member of}}
77 template <typename T
> A::B
<T
> E::func5() { return {}; }
78 template <typename T
> A::C
E::func6() { return {}; }
79 template <typename T
> A::D
<int> E::func7() { return {}; }
80 // expected-error@+1 {{is a private member of}}
81 template <typename T
> void E::func8(A::B
<T
>, int) {}
82 template <typename T
> void E::func9(A::C
, A::D
<T
>, int) {}
86 template <> void E::func1
<A::B
<int>>() {}
87 template <> void E::func2
<class A::C
>() {}
88 template <> void E::func3
<class A::D
<int>>() {
89 } template <> class A::B
<int> E::func4
<A::B
<int>>() {
91 } template <> A::B
<A::C
> E::func5
<A::C
>() {
94 template <> class A::C
E::func6
<A::D
<int>>() { return {}; } template <> A::D
<int> E::func7
<int>() {
97 template <> void E::func8
<int>(class A::B
<int>, int) {}
98 template <> void E::func9
<A::C
>(A::C
, A::D
<A::C
>, int) {}
102 template <> void E::func1
<A::B
<int>>();
103 template <> void E::func2
<class A::C
>();
104 template <> void E::func3
<class A::D
<int>>();
105 template <> class A::B
<int> E::func4
<A::B
<int>>();
106 template <> A::B
<A::C
> E::func5
<A::C
>();
107 template <> class A::C
E::func6
<A::D
<int>>();
108 template <> A::D
<int> E::func7
<int>();
109 template <> void E::func8
<int>(class A::B
<int>, int);
110 template <> void E::func9
<A::C
>(A::C
, A::D
<A::C
>, int);
112 //----------------------------------------------------------//
114 // forward declarations
116 // expected-error@+1 {{is a protected member of}}
117 template <typename T
> class A::C
func1();
118 // expected-error@+1 {{is a private member of}}
119 template <typename T
> A::B
<T
> func2();
120 template <typename T
> A::D
<T
> func3();
121 // expected-error@+1 {{is a private member of}}
122 template <typename T
> class A::B
<int> func4();
123 template <typename T
> void func5();
124 // expected-error@+1 {{is a private member of}}
125 template <int x
= A::num1
> void func6();
126 // expected-error@+1 {{is a protected member of}}
127 template <int x
= A::num2
> void func7();
128 // expected-error@+1 {{is a protected member of}}
129 template <typename T
> void func8(int x
= sizeof(A::C
));
130 // expected-error@+1 {{is a private member of}}
131 template <typename T
> void func9(int x
= A::num1
);
132 // expected-error@+2 {{is a private member of}}
133 // expected-error@+1 {{is a protected member of}}
134 template <typename T
> void func10(class A::B
<T
>, int x
= A::num2
);
135 // expected-error@+1 {{is a protected member of}}
136 template <typename T
> void func11(class A::C
, A::D
<T
>, int = A::num3
);
137 template <typename T
> void func12();
138 template <int x
> void func13();
139 template <typename T
, int x
> void func14();
140 template <template <typename
> typename T
> void func15();
141 // expected-error@+1 {{is a protected member of}}
142 template <typename T
= A::C
> void func16();
143 // expected-error@+1 {{is a private member of}}
144 template <typename T
= A::B
<int>> void func17();
145 // expected-error@+1 {{is a protected member of}}
146 template <typename T
> auto func18() -> A::C
;
147 template <typename T
> T
func19();
149 //----------------------------------------------------------//
153 // expected-error@+1 2{{is a protected member of}}
154 template <typename T
> A::C
func1() { A::C x
; }
155 // expected-error@+2 {{is a private member of}}
156 // expected-error@+1 {{is a protected member of}}
157 template <typename T
> A::B
<T
> func2() { A::D
<A::C
> x
; }
158 template <typename T
> A::D
<T
> func3() { A::D
<int> x
; }
159 // expected-error@+2 2{{is a private member of}}
160 // expected-error@+1 {{is a protected member of}}
161 template <typename T
> class A::B
<int> func4() { A::B
<A::C
> x
; }
163 template <typename T
>
165 // expected-error@+2 {{is a private member of}}
166 // expected-error@+1 {{is a protected member of}}
168 // expected-error@+1 {{is a private member of}}
171 template <typename T
> void func8(int x
) {}
172 template <typename T
> void func9(int x
) {}
173 // expected-error@+1 {{is a private member of}}
174 template <typename T
> void func10(A::B
<T
>, int x
) {}
175 // expected-error@+1 {{is a protected member of}}
176 template <typename T
> void func11(A::C
, A::D
<T
>, int) {}
177 template <typename T
> void func12() {}
178 template <int x
> void func13() {}
179 template <typename T
, int x
> void func14() {}
180 template <template <typename
> typename T
> void func15() {}
181 template <typename T
> void func16() {}
182 template <typename T
> void func17() {}
183 // expected-error@+1 {{is a protected member of}}
184 template <typename T
> auto func18() -> A::C
{
185 // expected-error@+1 {{is a protected member of}}
188 template <typename T
> T
func19() {
192 //----------------------------------------------------------//
194 // explicit specializations
196 template <> A::C func1
<A::C
>();
197 template <> A::B
<A::C
> func2
<A::C
>();
198 template <> A::D
<A::C
> func3
<A::C
>();
199 template <> class A::B
<int> func4
<A::C
>();
200 template <> void func5
<A::C
>();
201 template <> void func5
<A::B
<int>>();
202 template <> void func5
<A::D
<A::C
>>();
203 template <> void func5
<int>();
204 template <> void func8
<A::C
>(int x
);
205 template <> void func9
<decltype(A::num1
)>(int);
206 template <> void func10
<A::D
<int>>(A::B
<A::D
<int>>, int);
207 template <> void func11
<A::C
>(A::C
, A::D
<A::C
>, int);
208 template <> void func12
<class A::B
<char>>() {
209 } template <> void func13
<A::num1
>() {
211 template <> void func14
<A::B
<int>, A::num2
>() {}
212 template <> void func15
<A::D
>() {}
213 template <> void func16
<class A::B
<char>>() {
214 } template <> void func17
<A::B
<class A::C
>>() {
216 template <> auto func18
<int>() -> class A::C
;
217 template <> A::B
<int> func19
<class A::B
<int>>();
219 //----------------------------------------------------------//
221 // explicit instantiations
223 template void func10
<A::C
>(A::B
<A::C
>, decltype(A::num1
));
224 template void func11
<A::B
<int>>(A::C
, A::D
<A::B
<int>>, decltype(A::num2
));
225 template void func12
<A::C
>();
226 template void func13
<A::num2
>();
227 template void func13
<A::num3
>();
228 template void func14
<A::C
, A::num1
>();
229 template void func15
<A::B
>();
230 template void func17();
231 template auto func18
<char>() -> A::C
;
232 template class A::C func19
<A::C
>();
234 //----------------------------------------------------------//
238 template <int *x
> class StealClass
{
239 friend int stealFunc() { return *x
; }
242 template class StealClass
<&A::num4
>;