p2-0x.cpp revision 459455b9868974e2bb98032f768fe111ff376ada
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3// This test creates cases where implicit instantiations of various entities
4// would cause a diagnostic, but provides expliict specializations for those
5// entities that avoid the diagnostic. The specializations are alternately
6// declarations and definitions, and the intent of this test is to verify
7// that we allow specializations only in the appropriate namespaces (and
8// nowhere else).
9struct NonDefaultConstructible {
10  NonDefaultConstructible(int);
11};
12
13
14// C++ [temp.expl.spec]p1:
15//   An explicit specialization of any of the following:
16
17//     -- function template
18namespace N0 {
19  template<typename T> void f0(T) {
20    T t;
21  }
22
23  template<> void f0(NonDefaultConstructible) { }
24
25  void test_f0(NonDefaultConstructible NDC) {
26    f0(NDC);
27  }
28
29  template<> void f0(int);
30  template<> void f0(long);
31}
32
33template<> void N0::f0(int) { } // okay
34
35namespace N1 {
36  template<> void N0::f0(long) { } // expected-error{{does not enclose namespace}}
37}
38
39template<> void N0::f0(double) { }
40
41struct X1 {
42  template<typename T> void f(T);
43
44  template<> void f(int); // expected-error{{in class scope}}
45};
46
47//     -- class template
48namespace N0 {
49
50template<typename T>
51struct X0 { // expected-note {{here}}
52  static T member;
53
54  void f1(T t) {
55    t = 17;
56  }
57
58  struct Inner : public T { }; // expected-note 2{{here}}
59
60  template<typename U>
61  struct InnerTemplate : public T { }; // expected-note 1{{explicitly specialized}} \
62   // expected-error{{base specifier}}
63
64  template<typename U>
65  void ft1(T t, U u);
66};
67
68}
69
70template<typename T>
71template<typename U>
72void N0::X0<T>::ft1(T t, U u) {
73  t = u;
74}
75
76template<typename T> T N0::X0<T>::member;
77
78template<> struct N0::X0<void> { };
79N0::X0<void> test_X0;
80
81namespace N1 {
82  template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' must originally be declared in namespace 'N0'}}
83}
84
85namespace N0 {
86  template<> struct X0<volatile void>;
87}
88
89template<> struct N0::X0<volatile void> {
90  void f1(void *);
91};
92
93//     -- member function of a class template
94template<> void N0::X0<void*>::f1(void *) { }
95
96void test_spec(N0::X0<void*> xvp, void *vp) {
97  xvp.f1(vp);
98}
99
100namespace N0 {
101  template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
102
103  template<> void X0<const volatile void*>::f1(const volatile void*);
104}
105
106void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
107  x0.f1(cvp); // okay: we've explicitly specialized
108}
109
110//     -- static data member of a class template
111namespace N0 {
112  // This actually tests p15; the following is a declaration, not a definition.
113  template<>
114  NonDefaultConstructible X0<NonDefaultConstructible>::member;
115
116  template<> long X0<long>::member = 17;
117
118  template<> float X0<float>::member;
119
120  template<> double X0<double>::member;
121}
122
123NonDefaultConstructible &get_static_member() {
124  return N0::X0<NonDefaultConstructible>::member;
125}
126
127template<> int N0::X0<int>::member;
128
129template<> float N0::X0<float>::member = 3.14f;
130
131namespace N1 {
132  template<> double N0::X0<double>::member = 3.14; // expected-error{{does not enclose namespace}}
133}
134
135//    -- member class of a class template
136namespace N0 {
137
138  template<>
139  struct X0<void*>::Inner { };
140
141  template<>
142  struct X0<int>::Inner { };
143
144  template<>
145  struct X0<unsigned>::Inner;
146
147  template<>
148  struct X0<float>::Inner;
149
150  template<>
151  struct X0<double>::Inner; // expected-note{{forward declaration}}
152}
153
154template<>
155struct N0::X0<long>::Inner { };
156
157template<>
158struct N0::X0<float>::Inner { };
159
160namespace N1 {
161  template<>
162  struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}
163
164  template<>
165  struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}
166};
167
168N0::X0<void*>::Inner inner0;
169N0::X0<int>::Inner inner1;
170N0::X0<long>::Inner inner2;
171N0::X0<float>::Inner inner3;
172N0::X0<double>::Inner inner4; // expected-error{{incomplete}}
173
174//    -- member class template of a class template
175namespace N0 {
176  template<>
177  template<>
178  struct X0<void*>::InnerTemplate<int> { };
179
180  template<> template<>
181  struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}
182
183  template<> template<>
184  struct X0<int>::InnerTemplate<long>;
185
186  template<> template<>
187  struct X0<int>::InnerTemplate<double>;
188}
189
190template<> template<>
191struct N0::X0<int>::InnerTemplate<long> { }; // okay
192
193template<> template<>
194struct N0::X0<int>::InnerTemplate<float> { };
195
196namespace N1 {
197  template<> template<>
198  struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}
199}
200
201N0::X0<void*>::InnerTemplate<int> inner_template0;
202N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}
203N0::X0<int>::InnerTemplate<long> inner_template2;
204N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
205
206//    -- member function template of a class template
207namespace N0 {
208  template<>
209  template<>
210  void X0<void*>::ft1(void*, const void*) { }
211
212  template<> template<>
213  void X0<void*>::ft1(void *, int);
214
215  template<> template<>
216  void X0<void*>::ft1(void *, unsigned);
217
218  template<> template<>
219  void X0<void*>::ft1(void *, long);
220}
221
222template<> template<>
223void N0::X0<void*>::ft1(void *, unsigned) { } // okay
224
225template<> template<>
226void N0::X0<void*>::ft1(void *, float) { }
227
228namespace N1 {
229  template<> template<>
230  void N0::X0<void*>::ft1(void *, long) { } // expected-error{{does not enclose namespace}}
231}
232
233
234void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
235                        int i, unsigned u) {
236  xvp.ft1(vp, cvp);
237  xvp.ft1(vp, i);
238  xvp.ft1(vp, u);
239}
240
241namespace has_inline_namespaces {
242  inline namespace inner {
243    template<class T> void f(T&);
244
245    template<class T>
246    struct X0 {
247      struct MemberClass;
248
249      void mem_func();
250
251      template<typename U>
252      struct MemberClassTemplate;
253
254      template<typename U>
255      void mem_func_template(U&);
256
257      static int value;
258    };
259  }
260
261  struct X1;
262  struct X2;
263
264  // An explicit specialization whose declarator-id is not qualified
265  // shall be declared in the nearest enclosing namespace of the
266  // template, or, if the namespace is inline (7.3.1), any namespace
267  // from its enclosing namespace set.
268  template<> void f(X1&);
269  template<> void f<X2>(X2&);
270
271  template<> struct X0<X1> { };
272
273  template<> struct X0<X2>::MemberClass { };
274
275  template<> void X0<X2>::mem_func();
276
277  template<> template<typename T> struct X0<X2>::MemberClassTemplate { };
278
279  template<> template<typename T> void X0<X2>::mem_func_template(T&) { }
280
281  template<> int X0<X2>::value = 12;
282}
283
284struct X3;
285struct X4;
286
287template<> void has_inline_namespaces::f(X3&);
288template<> void has_inline_namespaces::f<X4>(X4&);
289
290template<> struct has_inline_namespaces::X0<X3> { };
291
292template<> struct has_inline_namespaces::X0<X4>::MemberClass { };
293
294template<> void has_inline_namespaces::X0<X4>::mem_func();
295
296template<> template<typename T>
297struct has_inline_namespaces::X0<X4>::MemberClassTemplate { };
298
299template<> template<typename T>
300void has_inline_namespaces::X0<X4>::mem_func_template(T&) { }
301
302template<> int has_inline_namespaces::X0<X4>::value = 13;
303
304namespace PR12938 {
305  template<typename> [[noreturn]] void func();
306  template<> void func<int>();
307}
308