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