Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CXX / temp / temp.spec / temp.expl.spec / p2.cpp
blob904f950df44332959842ba82d5b7acbecf41531a
1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
6 // This test creates cases where implicit instantiations of various entities
7 // would cause a diagnostic, but provides expliict specializations for those
8 // entities that avoid the diagnostic. The specializations are alternately
9 // declarations and definitions, and the intent of this test is to verify
10 // that we allow specializations only in the appropriate namespaces (and
11 // nowhere else).
12 struct NonDefaultConstructible {
13 NonDefaultConstructible(int);
17 // C++ [temp.expl.spec]p1:
18 // An explicit specialization of any of the following:
20 // -- function template
21 namespace N0 {
22 template<typename T> void f0(T) {
23 T t;
26 template<> void f0(NonDefaultConstructible) { }
28 void test_f0(NonDefaultConstructible NDC) {
29 f0(NDC);
32 template<> void f0(int);
33 template<> void f0(long);
36 template<> void N0::f0(int) { } // okay
38 namespace N1 {
39 template<> void N0::f0(long) { } // expected-error{{does not enclose namespace}}
42 template<> void N0::f0(double);
44 template<> void N0::f0(double) { }
46 struct X1 {
47 template<typename T> void f(T);
49 template<> void f(int);
52 // -- class template
53 namespace N0 {
55 template<typename T>
56 struct X0 { // expected-note {{explicitly specialized declaration is here}}
57 static T member;
59 void f1(T t) {
60 t = 17;
63 struct Inner : public T { }; // expected-note 2{{explicitly specialized declaration is here}}
65 template<typename U>
66 struct InnerTemplate : public T { }; // expected-note {{explicitly specialized declaration is here}}
67 // expected-error@-1 {{base specifier must name a class}}
69 template<typename U>
70 void ft1(T t, U u);
75 template<typename T>
76 template<typename U>
77 void N0::X0<T>::ft1(T t, U u) {
78 t = u;
81 template<typename T> T N0::X0<T>::member;
83 template<> struct N0::X0<void> { };
84 N0::X0<void> test_X0;
86 namespace N1 {
87 template<> struct N0::X0<const void> { }; // expected-error{{not in a namespace enclosing 'N0'}}
90 namespace N0 {
91 template<> struct X0<volatile void>;
94 template<> struct N0::X0<volatile void> {
95 void f1(void *);
98 // -- member function of a class template
99 template<> void N0::X0<void*>::f1(void *) { }
101 void test_spec(N0::X0<void*> xvp, void *vp) {
102 xvp.f1(vp);
105 namespace N0 {
106 template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
108 template<> void X0<const volatile void*>::f1(const volatile void*);
111 void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
112 x0.f1(cvp); // okay: we've explicitly specialized
115 // -- static data member of a class template
116 namespace N0 {
117 // This actually tests p15; the following is a declaration, not a definition.
118 template<>
119 NonDefaultConstructible X0<NonDefaultConstructible>::member;
121 template<> long X0<long>::member = 17;
123 template<> float X0<float>::member;
125 template<> double X0<double>::member;
128 NonDefaultConstructible &get_static_member() {
129 return N0::X0<NonDefaultConstructible>::member;
132 template<> int N0::X0<int>::member;
134 template<> float N0::X0<float>::member = 3.14f;
136 namespace N1 {
137 template<> double N0::X0<double>::member = 3.14; // expected-error{{does not enclose namespace}}
140 // -- member class of a class template
141 namespace N0 {
143 template<>
144 struct X0<void*>::Inner { };
146 template<>
147 struct X0<int>::Inner { };
149 template<>
150 struct X0<unsigned>::Inner;
152 template<>
153 struct X0<float>::Inner;
155 template<>
156 struct X0<double>::Inner; // expected-note{{forward declaration}}
159 template<>
160 struct N0::X0<long>::Inner { };
162 template<>
163 struct N0::X0<float>::Inner { };
165 namespace N1 {
166 template<>
167 struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}
169 template<>
170 struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}
173 N0::X0<void*>::Inner inner0;
174 N0::X0<int>::Inner inner1;
175 N0::X0<long>::Inner inner2;
176 N0::X0<float>::Inner inner3;
177 N0::X0<double>::Inner inner4; // expected-error{{incomplete}}
179 // -- member class template of a class template
180 namespace N0 {
181 template<>
182 template<>
183 struct X0<void*>::InnerTemplate<int> { };
185 template<> template<>
186 struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}
188 template<> template<>
189 struct X0<int>::InnerTemplate<long>;
191 template<> template<>
192 struct X0<int>::InnerTemplate<double>;
195 template<> template<>
196 struct N0::X0<int>::InnerTemplate<long> { }; // okay
198 template<> template<>
199 struct N0::X0<int>::InnerTemplate<float> { };
201 namespace N1 {
202 template<> template<>
203 struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}
206 N0::X0<void*>::InnerTemplate<int> inner_template0;
207 N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}
208 N0::X0<int>::InnerTemplate<long> inner_template2;
209 N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
211 // -- member function template of a class template
212 namespace N0 {
213 template<>
214 template<>
215 void X0<void*>::ft1(void*, const void*) { }
217 template<> template<>
218 void X0<void*>::ft1(void *, int);
220 template<> template<>
221 void X0<void*>::ft1(void *, unsigned);
223 template<> template<>
224 void X0<void*>::ft1(void *, long);
227 template<> template<>
228 void N0::X0<void*>::ft1(void *, unsigned) { } // okay
230 template<> template<>
231 void N0::X0<void*>::ft1(void *, float) { }
233 namespace N1 {
234 template<> template<>
235 void N0::X0<void*>::ft1(void *, long) { } // expected-error{{does not enclose namespace}}
239 void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
240 int i, unsigned u) {
241 xvp.ft1(vp, cvp);
242 xvp.ft1(vp, i);
243 xvp.ft1(vp, u);
246 namespace PR8979 {
247 template<typename Z>
248 struct X0 {
249 template <class T, class U> class Inner;
250 struct OtherInner;
251 template<typename T, typename U> void f(Inner<T, U>&);
253 typedef Inner<OtherInner, OtherInner> MyInner;
254 template<> void f(MyInner&);