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