1 // RUN: %clang_cc1 -verify -fsyntax-only -Wno-c++11-extensions -Wno-c++1y-extensions %s -DPRECXX11 2 // RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -Wno-c++1y-extensions %s 3 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only %s 4 5 #ifdef PRECXX11 6 #define CONST const 7 #else 8 #define CONST constexpr 9 #endif 10 11 template<typename T> 12 T pi = T(3.1415926535897932385); // expected-note {{template is declared here}} 13 14 template<typename T> 15 CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}} 16 17 template<typename T> extern CONST T vc; 18 #ifndef PRECXX11 19 // expected-error@-2 {{constexpr variable declaration must be a definition}} 20 #endif 21 22 namespace use_in_top_level_funcs { 23 good()24 void good() { 25 int ipi = pi<int>; 26 int icpi = cpi<int>; 27 double dpi = pi<double>; 28 double dcpi = cpi<double>; 29 } 30 no_deduce()31 void no_deduce() { 32 // template arguments are not deduced for uses of variable templates. 33 int ipi = pi; // expected-error {{cannot refer to variable template 'pi' without a template argument list}} 34 int icpi = cpi; // expected-error {{cannot refer to variable template 'cpi' without a template argument list}} 35 } 36 37 template<typename T> circular_area(T r)38 T circular_area(T r) { 39 return pi<T> * r * r; 40 } 41 42 template<typename T> const_circular_area(T r)43 CONST T const_circular_area(T r) { 44 return cpi<T> * r * r; 45 } 46 use_circular_area(double r)47 double use_circular_area(double r) { 48 CONST float t = const_circular_area(2.0) - 12; 49 #ifndef PRECXX11 50 static_assert(const_circular_area(2) == 12, ""); 51 CONST int test = (t > 0) && (t < 1); 52 static_assert(test, ""); 53 #endif 54 return circular_area(r); 55 } 56 } 57 58 namespace shadow { foo()59 void foo() { 60 int ipi0 = pi<int>; 61 int pi; 62 int a = pi; 63 int ipi = pi<int>; // expected-error {{expected '(' for function-style cast or type construction}} \ 64 // expected-error {{expected expression}} 65 } 66 } 67 68 namespace odr_tmpl { 69 namespace pv_cvt { 70 int v; // expected-note {{previous definition is here}} 71 template<typename T> T v; // expected-error {{redefinition of 'v' as different kind of symbol}} 72 } 73 namespace pvt_cv { 74 template<typename T> T v; // expected-note {{previous definition is here}} 75 int v; // expected-error {{redefinition of 'v' as different kind of symbol}} 76 } 77 namespace pvt_cvt { 78 template<typename T> T v0; // expected-note {{previous definition is here}} 79 template<typename T> T v0; // expected-error {{redefinition of 'v0'}} 80 81 template<typename T> T v; // expected-note {{previous definition is here}} 82 template<typename T> int v; // expected-error {{redefinition of 'v'}} 83 84 template<typename T> extern int v1; // expected-note {{previous template declaration is here}} 85 template<int I> int v1; // expected-error {{template parameter has a different kind in template redeclaration}} 86 } 87 namespace pvt_use { 88 template<typename T> T v; 89 v = 10; // expected-error {{C++ requires a type specifier for all declarations}} 90 } 91 92 namespace pvt_diff_params { 93 template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}} 94 template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}} 95 template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}} 96 } 97 98 namespace pvt_extern { 99 template<typename T> T v = T(); 100 template<typename T> extern T v; // redeclaration is allowed \ 101 // expected-note {{previous declaration is here}} 102 template<typename T> extern int v; // expected-error {{redeclaration of 'v' with a different type: 'int' vs 'T'}} 103 104 #ifndef PRECXX11 105 template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}} 106 #endif 107 108 template<typename T> T var = T(); // expected-note {{previous definition is here}} 109 extern int var; // expected-error {{redefinition of 'var' as different kind of symbol}} 110 } 111 112 #ifndef PRECXX11 113 namespace pvt_auto { 114 template<typename T> auto v0; // expected-error {{declaration of variable 'v0' with type 'auto' requires an initializer}} 115 template<typename T> auto v1 = T(); // expected-note {{previous definition is here}} 116 template<typename T> int v1; // expected-error {{redefinition of 'v1' with a different type: 'int' vs 'auto'}} 117 template<typename T> auto v2 = T(); // expected-note {{previous definition is here}} 118 template<typename T> T v2; // expected-error {{redefinition of 'v2'}} 119 template<typename T> auto v3 = T(); // expected-note {{previous definition is here}} 120 template<typename T> extern T v3; // expected-error {{redeclaration of 'v3' with a different type: 'T' vs 'auto'}} 121 template<typename T> auto v4 = T(); 122 template<typename T> extern auto v4; // expected-error {{declaration of variable 'v4' with type 'auto' requires an initializer}} 123 } 124 #endif 125 126 } 127 128 namespace explicit_instantiation { 129 template<typename T> 130 T pi0a = T(3.1415926535897932385); // expected-note {{variable template 'pi0a' declared here}} 131 template float pi0a<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0a' does not match expected type 'int'}} 132 133 template<typename T> 134 T pi0b = T(3.1415926535897932385); // expected-note {{variable template 'pi0b' declared here}} 135 template CONST int pi0b<int>; // expected-error {{type 'const int' of explicit instantiation of 'pi0b' does not match expected type 'int'}} 136 137 template<typename T> 138 T pi0c = T(3.1415926535897932385); // expected-note {{variable template 'pi0c' declared here}} 139 template int pi0c<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi0c' does not match expected type 'const int'}} 140 141 template<typename T> 142 T pi0 = T(3.1415926535897932385); 143 template int pi0<int>; // expected-note {{previous explicit instantiation is here}} 144 template int pi0<int>; // expected-error {{duplicate explicit instantiation of 'pi0<int>'}} 145 146 template<typename T> 147 CONST T pi1a = T(3.1415926535897932385); // expected-note {{variable template 'pi1a' declared here}} 148 template int pi1a<int>; // expected-error {{type 'int' of explicit instantiation of 'pi1a' does not match expected type 'const int'}} 149 150 template<typename T> 151 CONST T pi1b = T(3.1415926535897932385); // expected-note {{variable template 'pi1b' declared here}} 152 template int pi1b<const int>; // expected-error {{type 'int' of explicit instantiation of 'pi1b' does not match expected type 'const const int'}} 153 154 template<typename T> 155 CONST T pi1 = T(3.1415926535897932385); 156 template CONST int pi1<int>; // expected-note {{previous explicit instantiation is here}} 157 template CONST int pi1<int>; // expected-error {{duplicate explicit instantiation of 'pi1<int>'}} 158 159 #ifndef PRECXX11 160 namespace auto_var { 161 template<typename T> auto var0 = T(); 162 template auto var0<int>; // expected-error {{'auto' variable template instantiation is not allowed}} 163 164 template<typename T> auto var = T(); 165 template int var<int>; 166 } 167 #endif 168 169 template<typename=int> int missing_args; // expected-note {{here}} 170 template int missing_args; // expected-error {{must specify a template argument list}} 171 172 namespace extern_var { 173 // TODO: 174 } 175 } 176 177 namespace explicit_specialization { 178 179 namespace good { 180 template<typename T1, typename T2> 181 CONST int pi2 = 1; 182 183 template<typename T> 184 CONST int pi2<T,int> = 2; 185 186 template<typename T> 187 CONST int pi2<int,T> = 3; 188 189 template<> CONST int pi2<int,int> = 4; 190 191 #ifndef PRECXX11 foo()192 void foo() { 193 static_assert(pi2<int,int> == 4, ""); 194 static_assert(pi2<float,int> == 2, ""); 195 static_assert(pi2<int,float> == 3, ""); 196 static_assert(pi2<int,float> == pi2<int,double>, ""); 197 static_assert(pi2<float,float> == 1, ""); 198 static_assert(pi2<float,float> == pi2<float,double>, ""); 199 } 200 #endif 201 } 202 203 namespace ambiguous { 204 205 template<typename T1, typename T2> 206 CONST int pi2 = 1; 207 208 template<typename T> 209 CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}} 210 211 template<typename T> 212 CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}} 213 foo()214 void foo() { 215 int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}} 216 } 217 } 218 219 namespace type_changes { 220 221 template<typename T> 222 T pi0 = T(3.1415926535897932385); 223 224 template<> float pi0<int> = 10; 225 template<> int pi0<const int> = 10; 226 227 template<typename T> 228 T pi1 = T(3.1415926535897932385); 229 template<> CONST int pi1<int> = 10; 230 231 template<typename T> 232 T pi2 = T(3.1415926535897932385); 233 template<> int pi2<const int> = 10; 234 235 template<typename T> 236 CONST T pi4 = T(3.1415926535897932385); 237 template<> int pi4<int> = 10; 238 } 239 240 namespace redefinition { 241 template<typename T> 242 T pi0 = T(3.1415926535897932385); 243 244 template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}} 245 #ifndef PRECXX11 246 // expected-note@-2 {{previous definition is here}} 247 #endif 248 template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}} 249 template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}} 250 template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}} 251 #ifndef PRECXX11 252 template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}} 253 #endif 254 255 256 template<typename T> 257 CONST T pi1 = T(3.1415926535897932385); 258 259 template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}} 260 template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}} 261 } 262 263 namespace before_instantiation { 264 template<typename T> 265 T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}} 266 267 template<> int pi0<int> = 10; 268 template int pi0<int>; 269 template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} 270 271 template<typename T1, typename T2> 272 CONST int pi2 = 1; 273 274 template<typename T> CONST int pi2<T,int> = 2; 275 template CONST int pi2<int,int>; 276 } 277 namespace after_instantiation { 278 template<typename T> 279 T pi0 = T(3.1415926535897932385); 280 281 template int pi0<int>; // expected-note 2{{explicit instantiation first required here}} 282 template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}} 283 template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}} 284 285 template<typename T1, typename T2> 286 CONST int pi2 = 1; 287 288 template CONST int pi2<int,int>; 289 template<typename T> CONST int pi2<T,int> = 2; 290 } 291 292 #ifndef PRECXX11 293 namespace auto_var { 294 template<typename T, typename> auto var0 = T(); 295 template<typename T> auto var0<T,int> = T(); 296 template<> auto var0<int,int> = 7; 297 298 template<typename T, typename> auto var = T(); 299 template<typename T> T var<T,int> = T(5); 300 template<> int var<int,int> = 7; 301 foo()302 void foo() { 303 int i0 = var0<int,int>; 304 int b = var<int,int>; 305 } 306 } 307 #endif 308 309 namespace extern_var { 310 // TODO: 311 } 312 313 namespace diff_type { 314 // TODO: 315 template<typename T> T* var = new T(); 316 #ifndef PRECXX11 317 template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}} 318 template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}} 319 #endif 320 } 321 } 322 323 namespace narrowing { 324 template<typename T> T v = {1234}; // expected-warning {{implicit conversion from 'int' to 'char' changes value from 1234 to}} 325 #ifndef PRECXX11 326 // expected-error@-2 {{constant expression evaluates to 1234 which cannot be narrowed to type 'char'}}\ 327 // expected-note@-2 {{insert an explicit cast to silence this issue}} 328 #endif 329 int k = v<char>; // expected-note {{in instantiation of variable template specialization 'narrowing::v<char>' requested here}} 330 } 331 332 namespace use_in_structs { 333 // TODO: 334 } 335 336 namespace attributes { 337 // TODO: 338 } 339 340 #ifndef PRECXX11 341 namespace arrays { 342 template<typename T> 343 T* arr = new T[10]{T(10), T(23)}; 344 345 float f = 10.5; 346 template<> float* arr<float> = &f; 347 bar()348 void bar() { 349 int *iarr = arr<int>; 350 iarr[0] = 1; 351 iarr[2] = 3; 352 iarr[6] = -2; 353 354 float ff = *arr<float>; 355 float nof = arr<float>[3]; // No bounds-check in C++ 356 } 357 } 358 #endif 359 360 namespace nested { 361 362 namespace n0a { 363 template<typename T> 364 T pi0a = T(3.1415926535897932385); 365 } 366 367 using namespace n0a; 368 int i0a = pi0a<int>; 369 370 template float pi0a<float>; 371 float f0a = pi0a<float>; 372 373 template<> double pi0a<double> = 5.2; 374 double d0a = pi0a<double>; 375 376 namespace n0b { 377 template<typename T> 378 T pi0b = T(3.1415926535897932385); 379 } 380 381 int i0b = n0b::pi0b<int>; 382 383 template float n0b::pi0b<float>; 384 float f0b = n0b::pi0b<float>; 385 386 template<> double n0b::pi0b<double> = 5.2; 387 double d0b = n0b::pi0b<double>; 388 389 namespace n1 { 390 template<typename T> 391 T pi1a = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}} 392 #ifndef PRECXX11 393 // expected-note@-2 {{explicit instantiation refers here}} 394 #endif 395 396 template<typename T> 397 T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}} 398 #ifndef PRECXX11 399 // expected-note@-2 {{explicit instantiation refers here}} 400 #endif 401 } 402 403 namespace use_n1a { 404 using namespace n1; 405 int i1 = pi1a<int>; 406 407 template float pi1a<float>; 408 #ifndef PRECXX11 409 // expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}} 410 #endif 411 float f1 = pi1a<float>; 412 413 template<> double pi1a<double> = 5.2; // expected-error {{variable template specialization of 'pi1a' must originally be declared in namespace 'n1'}} 414 double d1 = pi1a<double>; 415 } 416 417 namespace use_n1b { 418 int i1 = n1::pi1b<int>; 419 420 template float n1::pi1b<float>; 421 #ifndef PRECXX11 422 // expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}} 423 #endif 424 float f1 = n1::pi1b<float>; 425 426 template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \ 427 // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}} 428 double d1 = n1::pi1b<double>; 429 } 430 } 431 432 namespace nested_name { 433 template<typename T> int a; // expected-note {{variable template 'a' declared here}} 434 a<int>::b c; // expected-error {{qualified name refers into a specialization of variable template 'a'}} 435 436 class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}} 437 enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}} 438 } 439 440 namespace PR18530 { 441 template<typename T> int a; 442 int a<int>; // expected-error {{requires 'template<>'}} 443 } 444 445 namespace PR19152 { 446 #ifndef PRECXX11 447 template<typename T> const auto x = 1; 448 static_assert(x<int> == 1, ""); 449 #endif 450 } 451 452 namespace PR19169 { 453 template <typename T> int* f(); 454 template <typename T> void f(); 455 template<> int f<double>; // expected-error {{no variable template matches specialization; did you mean to use 'f' as function template instead?}} 456 457 template <typename T> void g(); 458 template<> int g<double>; // expected-error {{no variable template matches specialization; did you mean to use 'g' as function template instead?}} 459 } 460 461