1 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify=expected,cxx98,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions -pedantic-errors 2 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 3 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions -fcxx-exceptions -pedantic-errors 4 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 5 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 6 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++23 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 7 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2c %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 8 9 #if __cplusplus == 199711L 10 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) 11 // cxx98-error@-1 {{variadic macros are a C99 feature}} 12 #endif 13 14 namespace cwg705 { // cwg705: 2.7 15 namespace N { 16 struct S {}; 17 void f(S); // #cwg705-f 18 } 19 20 void g() { 21 N::S s; 22 f(s); // ok 23 (f)(s); 24 // expected-error@-1 {{use of undeclared identifier 'f'}} 25 // expected-note@#cwg705-f {{'N::f' declared here}} 26 } 27 } // namespace cwg705 28 29 namespace cwg712 { // cwg712: partial 30 void use(int); 31 void f() { 32 const int a = 0; // #cwg712-f-a 33 struct X { 34 void g(bool cond) { 35 use(a); 36 use((a)); 37 use(cond ? a : a); 38 use((cond, a)); 39 // expected-warning@-1 {{left operand of comma operator has no effect}} 40 41 (void)a; 42 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME 43 // expected-note@#cwg712-f-a {{'a' declared here}} 44 (void)(a); 45 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME 46 // expected-note@#cwg712-f-a {{'a' declared here}} 47 (void)(cond ? a : a); // #cwg712-ternary 48 // expected-error@#cwg712-ternary {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME 49 // expected-note@#cwg712-f-a {{'a' declared here}} 50 // expected-error@#cwg712-ternary {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME 51 // expected-note@#cwg712-f-a {{'a' declared here}} 52 (void)(cond, a); // #cwg712-comma 53 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::f'}} FIXME 54 // expected-note@#cwg712-f-a {{'a' declared here}} 55 // expected-warning@#cwg712-comma {{left operand of comma operator has no effect}} 56 } 57 }; 58 } 59 60 #if __cplusplus >= 201103L 61 void g() { 62 struct A { int n; }; 63 constexpr A a = {0}; // #cwg712-g-a 64 struct X { 65 void g(bool cond) { 66 use(a.n); 67 use(a.*&A::n); 68 69 (void)a.n; 70 // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::g'}} FIXME 71 // since-cxx11-note@#cwg712-g-a {{'a' declared here}} 72 (void)(a.*&A::n); 73 // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg712::g'}} FIXME 74 // since-cxx11-note@#cwg712-g-a {{'a' declared here}} 75 } 76 }; 77 } 78 #endif 79 } // namespace cwg712 80 81 namespace cwg713 { // cwg713: 3.0 82 template<typename T> 83 struct is_const { 84 static const bool value = __is_const(T); 85 }; 86 template<typename T> 87 struct is_volatile { 88 static const bool value = __is_volatile(T); 89 }; 90 91 static_assert(!is_const<void()const>::value, ""); 92 static_assert(!is_const<void()const volatile>::value, ""); 93 static_assert(!is_volatile<void()volatile>::value, ""); 94 static_assert(!is_volatile<void()const volatile>::value, ""); 95 #if __cplusplus >= 201103L 96 static_assert(!is_const<void()const&>::value, ""); 97 static_assert(!is_volatile<void()volatile&>::value, ""); 98 #endif 99 } // namespace cwg713 100 101 // cwg722 is in cwg722.cpp 102 103 namespace cwg727 { // cwg727: partial 104 struct A { 105 template<typename T> struct C; // #cwg727-C 106 template<typename T> void f(); // #cwg727-f 107 template<typename T> static int N; // #cwg727-N 108 // cxx98-11-error@-1 {{variable templates are a C++14 extension}} 109 110 template<> struct C<int>; 111 template<> void f<int>(); 112 template<> int N<int>; 113 114 template<typename T> struct C<T*>; 115 template<typename T> static int N<T*>; 116 117 struct B { 118 template<> struct C<float>; 119 // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} 120 // expected-note@#cwg727-C {{explicitly specialized declaration is here}} 121 template<> void f<float>(); 122 // expected-error@-1 {{no function template matches function template specialization 'f'}} 123 template<> int N<float>; 124 // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} 125 // expected-note@#cwg727-N {{explicitly specialized declaration is here}} 126 127 template<typename T> struct C<T**>; 128 // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} 129 // expected-note@#cwg727-C {{explicitly specialized declaration is here}} 130 template<typename T> static int N<T**>; 131 // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} 132 // expected-note@#cwg727-N {{explicitly specialized declaration is here}} 133 134 template<> struct A::C<double>; 135 // expected-error@-1 {{non-friend class member 'C' cannot have a qualified name}} 136 // expected-error@-2 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} 137 // expected-note@#cwg727-C {{explicitly specialized declaration is here}} 138 template<> void A::f<double>(); 139 // expected-error@-1 {{o function template matches function template specialization 'f'}} 140 // expected-error@-2 {{non-friend class member 'f' cannot have a qualified name}} 141 template<> int A::N<double>; 142 // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}} 143 // expected-error@-2 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} 144 // expected-note@#cwg727-N {{explicitly specialized declaration is here}} 145 146 template<typename T> struct A::C<T***>; 147 // expected-error@-1 {{non-friend class member 'C' cannot have a qualified name}} 148 // expected-error@-2 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} 149 // expected-note@#cwg727-C {{explicitly specialized declaration is here}} 150 template<typename T> static int A::N<T***>; 151 // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}} 152 // expected-error@-2 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} 153 // expected-note@#cwg727-N {{explicitly specialized declaration is here}} 154 }; 155 }; 156 157 template<> struct A::C<char>; 158 template<> void A::f<char>(); 159 template<> int A::N<char>; 160 161 template<typename T> struct A::C<T****>; 162 template<typename T> int A::N<T****>; 163 164 namespace C { 165 template<> struct A::C<long>; 166 // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}} 167 // expected-note@#cwg727-C {{explicitly specialized declaration is here}} 168 template<> void A::f<long>(); 169 // expected-error@-1 {{function template specialization of 'f' not in class 'A' or an enclosing namespace}} 170 // expected-note@#cwg727-f {{explicitly specialized declaration is here}} 171 template<> int A::N<long>; 172 // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}} 173 // expected-note@#cwg727-N {{explicitly specialized declaration is here}} 174 175 template<typename T> struct A::C<T*****>; 176 // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}} 177 // expected-note@#cwg727-C {{explicitly specialized declaration is here}} 178 template<typename T> int A::N<T*****>; 179 // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}} 180 // expected-note@#cwg727-N {{explicitly specialized declaration is here}} 181 } 182 183 template<typename> 184 struct D { 185 template<typename T> struct C { typename T::error e; }; 186 // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} 187 // expected-note@#cwg727-C-float {{in instantiation of template class 'cwg727::D<int>::C<float>' requested here}} 188 template<typename T> void f() { T::error; } 189 // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}} 190 // expected-note@#cwg727-f-float {{in instantiation of function template specialization 'cwg727::D<int>::f<float>' requested here}} 191 template<typename T> static const int N = T::error; 192 // cxx98-11-error@-1 {{variable templates are a C++14 extension}} 193 // expected-error@-2 {{type 'float' cannot be used prior to '::' because it has no members}} 194 // expected-note@#cwg727-N-float {{in instantiation of static data member 'cwg727::D<int>::N<float>' requested here}} 195 196 template<> struct C<int> {}; 197 template<> void f<int>() {} 198 template<> const int N<int>; 199 200 template<typename T> struct C<T*> {}; 201 template<typename T> static const int N<T*>; 202 203 template<typename> 204 struct E { 205 template<> void f<void>() {} 206 // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}} 207 }; 208 }; 209 210 void d(D<int> di) { 211 D<int>::C<int>(); 212 di.f<int>(); 213 int a = D<int>::N<int>; 214 215 D<int>::C<int*>(); 216 int b = D<int>::N<int*>; 217 218 D<int>::C<float>(); // #cwg727-C-float 219 di.f<float>(); // #cwg727-f-float 220 int c = D<int>::N<float>; // #cwg727-N-float 221 } 222 223 namespace mixed_inner_outer_specialization { 224 #if __cplusplus >= 201103L 225 template<int> struct A { 226 template<int> constexpr int f() const { return 1; } 227 template<> constexpr int f<0>() const { return 2; } 228 }; 229 template<> template<int> constexpr int A<0>::f() const { return 3; } 230 template<> template<> constexpr int A<0>::f<0>() const { return 4; } 231 static_assert(A<1>().f<1>() == 1, ""); 232 static_assert(A<1>().f<0>() == 2, ""); 233 static_assert(A<0>().f<1>() == 3, ""); 234 static_assert(A<0>().f<0>() == 4, ""); 235 #endif 236 237 #if __cplusplus >= 201402L 238 template<int> struct B { 239 template<int> static const int u = 1; 240 template<> const int u<0> = 2; // #cwg727-u0 241 242 // Note that in C++17 onwards, these are implicitly inline, and so the 243 // initializer of v<0> is not instantiated with the declaration. In 244 // C++14, v<0> is a non-defining declaration and its initializer is 245 // instantiated with the class. 246 template<int> static constexpr int v = 1; 247 template<> constexpr int v<0> = 2; // #cwg727-v0 248 249 template<int> static const inline int w = 1; 250 // cxx14-error@-1 {{inline variables are a C++17 extension}} 251 template<> const inline int w<0> = 2; 252 // cxx14-error@-1 {{inline variables are a C++17 extension}} 253 }; 254 255 template<> template<int> constexpr int B<0>::u = 3; 256 template<> template<> constexpr int B<0>::u<0> = 4; 257 // since-cxx14-error@-1 {{static data member 'u' already has an initializer}} 258 // since-cxx14-note@#cwg727-u0 {{previous initialization is here}} 259 260 template<> template<int> constexpr int B<0>::v = 3; 261 template<> template<> constexpr int B<0>::v<0> = 4; 262 // cxx14-error@-1 {{static data member 'v' already has an initializer}} 263 // cxx14-note@#cwg727-v0 {{previous initialization is here}} 264 265 template<> template<int> constexpr int B<0>::w = 3; 266 template<> template<> constexpr int B<0>::w<0> = 4; 267 268 static_assert(B<1>().u<1> == 1, ""); 269 static_assert(B<1>().u<0> == 2, ""); 270 static_assert(B<0>().u<1> == 3, ""); 271 272 static_assert(B<1>().v<1> == 1, ""); 273 static_assert(B<1>().v<0> == 2, ""); 274 static_assert(B<0>().v<1> == 3, ""); 275 static_assert(B<0>().v<0> == 4, ""); 276 // cxx14-error@-1 {{static assertion failed due to requirement 'cwg727::mixed_inner_outer_specialization::B<0>().v<0> == 4'}} 277 // cxx14-note@-2 {{expression evaluates to '2 == 4'}} 278 279 static_assert(B<1>().w<1> == 1, ""); 280 static_assert(B<1>().w<0> == 2, ""); 281 static_assert(B<0>().w<1> == 3, ""); 282 static_assert(B<0>().w<0> == 4, ""); 283 #endif 284 } 285 286 template<typename T, typename U> struct Collision { 287 // FIXME: Missing diagnostic for duplicate function explicit specialization declaration. 288 template<typename> int f1(); 289 template<> int f1<T>(); 290 template<> int f1<U>(); 291 292 // FIXME: Missing diagnostic for fucntion redefinition! 293 template<typename> int f2(); 294 template<> int f2<T>() {} 295 template<> int f2<U>() {} 296 297 template<typename> static int v1; 298 // cxx98-11-error@-1 {{variable templates are a C++14 extension}} 299 template<> int v1<T>; // #cwg727-v1-T 300 template<> int v1<U>; 301 // expected-error@-1 {{duplicate member 'v1'}} 302 // expected-note@#cwg727-Collision-int-int {{in instantiation of template class 'cwg727::Collision<int, int>' requested here}} 303 // expected-note@#cwg727-v1-T {{previous}} 304 305 template<typename> static inline int v2; 306 // cxx98-11-error@-1 {{variable templates are a C++14 extension}} 307 // cxx98-14-error@-2 {{inline variables are a C++17 extension}} 308 template<> inline int v2<T>; // #cwg727-v2-T 309 // cxx98-14-error@-1 {{inline variables are a C++17 extension}} 310 template<> inline int v2<U>; 311 // cxx98-14-error@-1 {{inline variables are a C++17 extension}} 312 // expected-error@-2 {{duplicate member 'v2'}} 313 // expected-note@#cwg727-v2-T {{previous declaration is here}} 314 315 // FIXME: Missing diagnostic for duplicate class explicit specialization. 316 template<typename> struct S1; 317 template<> struct S1<T>; 318 template<> struct S1<U>; 319 320 template<typename> struct S2; 321 template<> struct S2<T> {}; // #cwg727-S2-T 322 template<> struct S2<U> {}; 323 // expected-error@-1 {{redefinition of 'S2<int>'}} 324 // expected-note@#cwg727-S2-T {{previous}} 325 }; 326 Collision<int, int> c; // #cwg727-Collision-int-int 327 } // namespace cwg727 328 329 namespace cwg777 { // cwg777: 3.7 330 #if __cplusplus >= 201103L 331 template <typename... T> 332 void f(int i = 0, T ...args) {} 333 void ff() { f(); } 334 335 template <typename... T> 336 void g(int i = 0, T ...args, T ...args2) {} 337 338 template <typename... T> 339 void h(int i = 0, T ...args, int j = 1) {} 340 #endif 341 } // namespace cwg777 342 343 namespace cwg794 { // cwg794: 2.7 344 struct B {}; 345 struct D : B {}; 346 struct X { 347 D d; 348 }; 349 struct Y : X {}; 350 B Y::*pm = &X::d; 351 // expected-error@-1 {{cannot initialize a variable of type 'B Y::*' with an rvalue of type 'D cwg794::X::*': different classes ('Y' vs 'cwg794::X')}} 352 // FIXME: why diagnostic says just `Y` and not `cwg794::Y`, like `cwg794::X`? 353 } // namespace cwg794 354