xref: /llvm-project/clang/test/CXX/temp/temp.spec/func.spec.cpp (revision 638dcea010cfc280f428d0cc13f4aa8578a1d69d)
1 // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s
2 
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]
13 
14 class A {
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;
19 
20 protected:
21   // expected-note@+1 13{{declared protected here}}
22   class C {};
23   // expected-note@+1 2{{declared protected here}}
24   static constexpr int num2 = 43;
25   static int num4;
26 
27 public:
28   template <typename T> class D {};
29   static constexpr int num3 = 44;
30 };
31 int A::num4 = 44;
32 
33 class E : public A {
34 
35   // Declarations
36 
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);
50 
51   // Specializations inside class declaration
func1()52   template <> void func1<A::B<char>>() {}
func2()53   template <> void func2<class A::D<char>>() {
54   } template <> void func3<class A::C>() {
55   }
56   template <> class A::B<int> func4<A::B<char>>() { return {}; } template <> A::B<A::D<int>> func5<A::D<int>>() {
57     return {};
58   }
func6()59   template <> class A::C func6<A::C>() { return {}; } template <> A::D<int> func7<char>() {
60     return {};
61   }
func8(class A::B<char>,int)62   template <> void func8<char>(class A::B<char>, int) {}
func9(A::C,A::D<A::B<char>>,int)63   template <> void func9<A::B<char>>(A::C, A::D<A::B<char>>, int) {}
64 
65   // FIXME: Instantiations inside class declaration.
66   // don't work correctly.
67 };
68 
69 // Definitions
70 
func1()71 template <typename T> void E::func1() {}
func2()72 template <typename T> void E::func2() {}
func3()73 template <typename T> void E::func3() {}
74 // expected-error@+1 {{is a private member of}}
func4()75 template <typename T> A::B<int> E::func4() { return {}; }
76 // expected-error@+1 {{is a private member of}}
func5()77 template <typename T> A::B<T> E::func5() { return {}; }
func6()78 template <typename T> A::C E::func6() { return {}; }
func7()79 template <typename T> A::D<int> E::func7() { return {}; }
80 // expected-error@+1 {{is a private member of}}
func8(A::B<T>,int)81 template <typename T> void E::func8(A::B<T>, int) {}
func9(A::C,A::D<T>,int)82 template <typename T> void E::func9(A::C, A::D<T>, int) {}
83 
84 // Specializations
85 
func1()86 template <> void E::func1<A::B<int>>() {}
func2()87 template <> void E::func2<class A::C>() {}
func3()88 template <> void E::func3<class A::D<int>>() {
89 } template <> class A::B<int> E::func4<A::B<int>>() {
90   return {};
func5()91 } template <> A::B<A::C> E::func5<A::C>() {
92   return {};
93 }
func7()94 template <> class A::C E::func6<A::D<int>>() { return {}; } template <> A::D<int> E::func7<int>() {
95   return {};
96 }
func8(class A::B<int>,int)97 template <> void E::func8<int>(class A::B<int>, int) {}
func9(A::C,A::D<A::C>,int)98 template <> void E::func9<A::C>(A::C, A::D<A::C>, int) {}
99 
100 // Instantiations
101 
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);
111 
112 //----------------------------------------------------------//
113 
114 // forward declarations
115 
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();
148 
149 //----------------------------------------------------------//
150 
151 // definitions
152 
153 // expected-error@+1 2{{is a protected member of}}
func1()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}}
func2()157 template <typename T> A::B<T> func2() { A::D<A::C> x; }
func3()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}}
func4()161 template <typename T> class A::B<int> func4() { A::B<A::C> x; }
162 
163 template <typename T>
func5()164 void func5() {
165   // expected-error@+2 {{is a private member of}}
166   // expected-error@+1 {{is a protected member of}}
167   A::B<A::D<A::C>> x;
168   // expected-error@+1 {{is a private member of}}
169   A::B<int> x2;
170 }
func8(int x)171 template <typename T> void func8(int x) {}
func9(int x)172 template <typename T> void func9(int x) {}
173 // expected-error@+1 {{is a private member of}}
func10(A::B<T>,int x)174 template <typename T> void func10(A::B<T>, int x) {}
175 // expected-error@+1 {{is a protected member of}}
func11(A::C,A::D<T>,int)176 template <typename T> void func11(A::C, A::D<T>, int) {}
func12()177 template <typename T> void func12() {}
func13()178 template <int x> void func13() {}
func14()179 template <typename T, int x> void func14() {}
func15()180 template <template <typename> typename T> void func15() {}
func16()181 template <typename T> void func16() {}
func17()182 template <typename T> void func17() {}
183 // expected-error@+1 {{is a protected member of}}
func18()184 template <typename T> auto func18() -> A::C {
185   // expected-error@+1 {{is a protected member of}}
186   return A::C{};
187 }
func19()188 template <typename T> T func19() {
189   return T{};
190 }
191 
192 //----------------------------------------------------------//
193 
194 // explicit specializations
195 
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);
func12()208 template <> void func12<class A::B<char>>() {
209 } template <> void func13<A::num1>() {
210 }
func14()211 template <> void func14<A::B<int>, A::num2>() {}
func15()212 template <> void func15<A::D>() {}
func16()213 template <> void func16<class A::B<char>>() {
214 } template <> void func17<A::B<class A::C>>() {
215 }
216 template <> auto func18<int>() -> class A::C;
217 template <> A::B<int> func19<class A::B<int>>();
218 
219 //----------------------------------------------------------//
220 
221 // explicit instantiations
222 
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>();
233 
234 //----------------------------------------------------------//
235 
236 // Other cases
237 
238 template <int *x> class StealClass {
stealFunc()239   friend int stealFunc() { return *x; }
240 };
241 
242 template class StealClass<&A::num4>;
243 int stealFunc();
244 
stealFunc2()245 int stealFunc2() {
246   return stealFunc();
247 }
248