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 | |
| 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 | |