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