Larisse Voufo | 39a1e50 | 2013-08-06 01:03:05 +0000 | [diff] [blame] | 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 | |
Larisse Voufo | a11bd8a | 2013-08-13 02:02:26 +0000 | [diff] [blame^] | 17 | template<typename T> extern CONST T vc; |
| 18 | #ifdef CXX11 |
| 19 | // expected-error@-2 {{constexpr variable declaration must be a definition}} |
| 20 | #endif |
| 21 | |
Larisse Voufo | 39a1e50 | 2013-08-06 01:03:05 +0000 | [diff] [blame] | 22 | namespace use_in_top_level_funcs { |
| 23 | |
| 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 | |
| 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> |
| 38 | T circular_area(T r) { |
| 39 | return pi<T> * r * r; |
| 40 | } |
| 41 | |
| 42 | template<typename T> |
| 43 | CONST T const_circular_area(T r) { |
| 44 | return cpi<T> * r * r; |
| 45 | } |
| 46 | |
| 47 | double use_circular_area(double r) { |
| 48 | CONST float t = const_circular_area(2.0) - 12; |
| 49 | #ifdef CXX11 |
| 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 { |
| 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' with a different type: 'int' vs 'T'}} |
| 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> 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 | // FIXME: (?) Redefinitions should simply be not allowed, whether the |
| 94 | // template parameters match or not. However, this current behaviour also |
| 95 | // matches that of class templates... |
| 96 | template<typename T, typename> T v; // expected-note 2{{previous template declaration is here}} |
| 97 | template<typename T> T v; // expected-error {{too few template parameters in template redeclaration}} |
| 98 | template<typename T, typename, typename> T v; // expected-error {{too many template parameters in template redeclaration}} |
| 99 | } |
| 100 | |
| 101 | namespace pvt_extern { |
| 102 | template<typename T> T v = T(); |
| 103 | template<typename T> extern T v; // redeclaration is allowed \ |
| 104 | // expected-note {{previous definition is here}} |
| 105 | template<typename T> extern int v; // expected-error {{redefinition of 'v' with a different type: 'int' vs 'T'}} |
| 106 | |
| 107 | #ifdef CXX11 |
| 108 | template<typename T> extern auto v; // expected-error {{declaration of variable 'v' with type 'auto' requires an initializer}} |
| 109 | #endif |
| 110 | } |
| 111 | |
| 112 | #ifdef CXX11 |
| 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 {{redefinition 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 | #ifdef CXX11 |
| 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 | namespace extern_var { |
| 170 | // TODO: |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | namespace explicit_specialization { |
| 175 | |
| 176 | namespace good { |
| 177 | template<typename T1, typename T2> |
| 178 | CONST int pi2 = 1; |
| 179 | |
| 180 | template<typename T> |
| 181 | CONST int pi2<T,int> = 2; |
| 182 | |
| 183 | template<typename T> |
| 184 | CONST int pi2<int,T> = 3; |
| 185 | |
| 186 | template<> CONST int pi2<int,int> = 4; |
| 187 | |
| 188 | #ifdef CXX11 |
| 189 | void foo() { |
| 190 | static_assert(pi2<int,int> == 4, ""); |
| 191 | static_assert(pi2<float,int> == 2, ""); |
| 192 | static_assert(pi2<int,float> == 3, ""); |
| 193 | static_assert(pi2<int,float> == pi2<int,double>, ""); |
| 194 | static_assert(pi2<float,float> == 1, ""); |
| 195 | static_assert(pi2<float,float> == pi2<float,double>, ""); |
| 196 | } |
| 197 | #endif |
| 198 | } |
| 199 | |
| 200 | namespace ambiguous { |
| 201 | |
| 202 | template<typename T1, typename T2> |
| 203 | CONST int pi2 = 1; |
| 204 | |
| 205 | template<typename T> |
| 206 | CONST int pi2<T,int> = 2; // expected-note {{partial specialization matches [with T = int]}} |
| 207 | |
| 208 | template<typename T> |
| 209 | CONST int pi2<int,T> = 3; // expected-note {{partial specialization matches [with T = int]}} |
| 210 | |
| 211 | void foo() { |
| 212 | int a = pi2<int,int>; // expected-error {{ambiguous partial specializations of 'pi2<int, int>'}} |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | namespace type_changes { |
| 217 | |
| 218 | template<typename T> |
| 219 | T pi0 = T(3.1415926535897932385); |
| 220 | |
| 221 | template<> float pi0<int> = 10; |
| 222 | template<> int pi0<const int> = 10; |
| 223 | |
| 224 | template<typename T> |
| 225 | T pi1 = T(3.1415926535897932385); |
| 226 | template<> CONST int pi1<int> = 10; |
| 227 | |
| 228 | template<typename T> |
| 229 | T pi2 = T(3.1415926535897932385); |
| 230 | template<> int pi2<const int> = 10; |
| 231 | |
| 232 | template<typename T> |
| 233 | CONST T pi4 = T(3.1415926535897932385); |
| 234 | template<> int pi4<int> = 10; |
| 235 | } |
| 236 | |
| 237 | namespace redefinition { |
| 238 | template<typename T> |
| 239 | T pi0 = T(3.1415926535897932385); |
| 240 | |
| 241 | template<> int pi0<int> = 10; // expected-note 3{{previous definition is here}} |
| 242 | #ifdef CXX11 |
| 243 | // expected-note@-2 {{previous definition is here}} |
| 244 | #endif |
| 245 | template<> int pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}} |
| 246 | template<> CONST int pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'const int' vs 'int'}} |
| 247 | template<> float pi0<int> = 10; // expected-error {{redefinition of 'pi0' with a different type: 'float' vs 'int'}} |
| 248 | #ifdef CXX11 |
| 249 | template<> auto pi0<int> = 10; // expected-error {{redefinition of 'pi0<int>'}} |
| 250 | #endif |
| 251 | |
| 252 | |
| 253 | template<typename T> |
| 254 | CONST T pi1 = T(3.1415926535897932385); |
| 255 | |
| 256 | template<> CONST int pi1<int> = 10; // expected-note {{previous definition is here}} |
| 257 | template<> CONST int pi1<int> = 10; // expected-error {{redefinition of 'pi1<int>'}} |
| 258 | } |
| 259 | |
| 260 | namespace before_instantiation { |
| 261 | template<typename T> |
| 262 | T pi0 = T(3.1415926535897932385); // expected-note {{variable template 'pi0' declared here}} |
| 263 | |
| 264 | template<> int pi0<int> = 10; |
| 265 | template int pi0<int>; |
| 266 | template float pi0<int>; // expected-error {{type 'float' of explicit instantiation of 'pi0' does not match expected type}} |
| 267 | |
| 268 | template<typename T1, typename T2> |
| 269 | CONST int pi2 = 1; |
| 270 | |
| 271 | template<typename T> CONST int pi2<T,int> = 2; |
| 272 | template CONST int pi2<int,int>; |
| 273 | } |
| 274 | namespace after_instantiation { |
| 275 | template<typename T> |
| 276 | T pi0 = T(3.1415926535897932385); |
| 277 | |
| 278 | template int pi0<int>; // expected-note 2{{explicit instantiation first required here}} |
| 279 | template<> int pi0<int> = 10; // expected-error {{explicit specialization of 'pi0' after instantiation}} |
| 280 | template<> float pi0<int>; // expected-error {{explicit specialization of 'pi0' after instantiation}} |
| 281 | |
| 282 | template<typename T1, typename T2> |
| 283 | CONST int pi2 = 1; |
| 284 | |
| 285 | template CONST int pi2<int,int>; |
| 286 | template<typename T> CONST int pi2<T,int> = 2; |
| 287 | } |
| 288 | |
| 289 | #ifdef CXX11 |
| 290 | namespace auto_var { |
| 291 | template<typename T, typename> auto var0 = T(); |
| 292 | template<typename T> auto var0<T,int> = T(); |
| 293 | template<> auto var0<int,int> = 7; |
| 294 | |
| 295 | template<typename T, typename> auto var = T(); |
| 296 | template<typename T> T var<T,int> = T(5); |
| 297 | template<> int var<int,int> = 7; |
| 298 | |
| 299 | void foo() { |
| 300 | int i0 = var0<int,int>; |
| 301 | int b = var<int,int>; |
| 302 | } |
| 303 | } |
| 304 | #endif |
| 305 | |
| 306 | namespace extern_var { |
| 307 | // TODO: |
| 308 | } |
| 309 | |
| 310 | namespace diff_type { |
| 311 | // TODO: |
| 312 | template<typename T> T var = T(); |
| 313 | template<typename T> T* var<T> = new T(); |
| 314 | #ifdef CXX11 |
| 315 | template<typename T> auto var<T*> = T(); // expected-note {{previous definition is here}} |
| 316 | template<typename T> T var<T*> = T(); // expected-error {{redefinition of 'var' with a different type: 'T' vs 'auto'}} |
| 317 | #endif |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | namespace use_in_structs { |
| 322 | // TODO: |
| 323 | } |
| 324 | |
| 325 | namespace attributes { |
| 326 | // TODO: |
| 327 | } |
| 328 | |
| 329 | #ifdef CXX11 |
| 330 | namespace arrays { |
| 331 | template<typename T> |
| 332 | T* arr = new T[10]{T(10), T(23)}; |
| 333 | |
| 334 | float f = 10.5; |
| 335 | template<> float* arr<float> = &f; |
| 336 | |
| 337 | void bar() { |
| 338 | int *iarr = arr<int>; |
| 339 | iarr[0] = 1; |
| 340 | iarr[2] = 3; |
| 341 | iarr[6] = -2; |
| 342 | |
| 343 | float ff = *arr<float>; |
| 344 | float nof = arr<float>[3]; // No bounds-check in C++ |
| 345 | } |
| 346 | } |
| 347 | #endif |
| 348 | |
| 349 | namespace nested { |
| 350 | |
| 351 | namespace n0a { |
| 352 | template<typename T> |
| 353 | T pi0a = T(3.1415926535897932385); |
| 354 | } |
| 355 | |
| 356 | using namespace n0a; |
| 357 | int i0a = pi0a<int>; |
| 358 | |
| 359 | template float pi0a<float>; |
| 360 | float f0a = pi0a<float>; |
| 361 | |
| 362 | template<> double pi0a<double> = 5.2; |
| 363 | double d0a = pi0a<double>; |
| 364 | |
| 365 | namespace n0b { |
| 366 | template<typename T> |
| 367 | T pi0b = T(3.1415926535897932385); |
| 368 | } |
| 369 | |
| 370 | int i0b = n0b::pi0b<int>; |
| 371 | |
| 372 | template float n0b::pi0b<float>; |
| 373 | float f0b = n0b::pi0b<float>; |
| 374 | |
| 375 | template<> double n0b::pi0b<double> = 5.2; |
| 376 | double d0b = n0b::pi0b<double>; |
| 377 | |
| 378 | namespace n1 { |
| 379 | template<typename T> |
| 380 | T pi1a = T(3.1415926535897932385); |
| 381 | #ifdef CXX11 |
| 382 | // expected-note@-2 {{explicit instantiation refers here}} |
| 383 | #endif |
| 384 | |
| 385 | template<typename T> |
| 386 | T pi1b = T(3.1415926535897932385); // expected-note {{explicitly specialized declaration is here}} |
| 387 | #ifdef CXX11 |
| 388 | // expected-note@-2 {{explicit instantiation refers here}} |
| 389 | #endif |
| 390 | } |
| 391 | |
| 392 | namespace use_n1a { |
| 393 | using namespace n1; |
| 394 | int i1 = pi1a<int>; |
| 395 | |
| 396 | template float pi1a<float>; |
| 397 | #ifdef CXX11 |
| 398 | // expected-error@-2 {{explicit instantiation of 'pi1a<float>' not in a namespace enclosing 'n1'}} |
| 399 | #endif |
| 400 | float f1 = pi1a<float>; |
| 401 | |
| 402 | template<> double pi1a<double> = 5.2; // expected-error {{no variable template matches specialization}} |
| 403 | double d1 = pi1a<double>; |
| 404 | } |
| 405 | |
| 406 | namespace use_n1b { |
| 407 | int i1 = n1::pi1b<int>; |
| 408 | |
| 409 | template float n1::pi1b<float>; |
| 410 | #ifdef CXX11 |
| 411 | // expected-error@-2 {{explicit instantiation of 'pi1b<float>' not in a namespace enclosing 'n1'}} |
| 412 | #endif |
| 413 | float f1 = n1::pi1b<float>; |
| 414 | |
| 415 | template<> double n1::pi1b<double> = 5.2; // expected-error {{cannot define or redeclare 'pi1b' here because namespace 'use_n1b' does not enclose namespace 'n1'}} \ |
| 416 | // expected-error {{variable template specialization of 'pi1b' must originally be declared in namespace 'n1'}} |
| 417 | double d1 = n1::pi1b<double>; |
| 418 | } |
| 419 | } |
| 420 | |