1 // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors 2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 3 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 4 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors 5 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors 6 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors 7 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors 8 9 namespace std { 10 struct type_info{}; 11 } // namespace std 12 13 // cwg2504 is in cwg2504.cpp 14 15 namespace cwg2512 { // cwg2512: 2.7 16 struct A; // #cwg2512-A 17 void foo(A* p) { 18 typeid(*p); 19 // expected-error@-1 {{'typeid' of incomplete type 'A'}} 20 // expected-note@#cwg2512-A {{forward declaration of 'cwg2512::A'}} 21 } 22 } // namespace cwg2512 23 24 namespace cwg2516 { // cwg2516: 3.0 25 // NB: reusing 1482 test 26 #if __cplusplus >= 201103L 27 template <typename T> struct S { 28 typedef char I; 29 }; 30 enum E2 : S<E2>::I { e }; 31 // since-cxx11-error@-1 {{use of undeclared identifier 'E2'}} 32 #endif 33 } // namespace cwg2516 34 35 namespace cwg2518 { // cwg2518: 17 36 37 #if __cplusplus >= 201103L 38 template <class T> 39 void f(T t) { 40 if constexpr (sizeof(T) != sizeof(int)) { 41 // cxx11-14-error@-1 {{constexpr if is a C++17 extension}} 42 static_assert(false, "must be int-sized"); 43 // since-cxx11-error@-1 {{static assertion failed: must be int-sized}} 44 // since-cxx11-note@#cwg2518-f-c {{in instantiation of function template specialization 'cwg2518::f<char>' requested here}} 45 } 46 } 47 48 void g(char c) { 49 f(0); 50 f(c); // #cwg2518-f-c 51 } 52 53 template <typename Ty> 54 struct S { 55 static_assert(false); 56 // cxx11-14-error@-1 {{'static_assert' with no message is a C++17 extension}} 57 // since-cxx11-error@-2 {{static assertion failed}} 58 // since-cxx11-note@#cwg2518-S-double {{in instantiation of template class 'cwg2518::S<double>' requested here}} 59 }; 60 61 template <> 62 struct S<int> {}; 63 64 template <> 65 struct S<float> {}; 66 67 int test_specialization() { 68 S<int> s1; 69 S<float> s2; 70 S<double> s3; // #cwg2518-S-double 71 } 72 #endif 73 74 } // namespace cwg2518 75 76 namespace cwg2521 { // cwg2521: 17 77 #if __cplusplus >= 201103L 78 #pragma clang diagnostic push 79 #pragma clang diagnostic warning "-Wdeprecated-literal-operator" 80 long double operator"" _\u03C0___(long double); 81 // since-cxx11-warning@-1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}} 82 // since-cxx11-warning@-2 {{user-defined literal suffixes containing '__' are reserved}} 83 84 template <char... Chars> decltype(sizeof 0) 85 operator"" _div(); 86 // since-cxx11-warning@-1 {{identifier '_div' preceded by whitespace in a literal operator declaration is deprecated}} 87 88 using ::cwg2521::operator"" _\u03C0___; 89 // since-cxx11-warning@-1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}} 90 using ::cwg2521::operator""_div; 91 92 long double operator"" _RESERVED(long double); 93 // since-cxx11-warning@-1 {{identifier '_RESERVED' preceded by whitespace in a literal operator declaration is deprecated}} 94 #pragma clang diagnostic pop 95 #endif 96 } // namespace cwg2521 97 98 namespace cwg2547 { // cwg2547: 20 99 #if __cplusplus >= 202302L 100 struct S; 101 // since-cxx23-note@-1 {{forward declaration of 'cwg2547::S'}} 102 // since-cxx23-note@-2 {{forward declaration of 'cwg2547::S'}} 103 // since-cxx23-note@-3 {{forward declaration of 'cwg2547::S'}} 104 bool operator==(S, S) = default; // error: S is not complete 105 // since-cxx23-error@-1 {{variable has incomplete type 'S'}} 106 // since-cxx23-error@-2 {{variable has incomplete type 'S'}} 107 // since-cxx23-error@-3 {{equality comparison operator is not a friend of incomplete class 'cwg2547::S'}} 108 struct S { 109 friend bool operator==(S, const S&) = default; // error: parameters of different types 110 // since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'S' vs 'const S &')}} 111 }; 112 enum E { }; 113 bool operator==(E, E) = default; // error: not a member or friend of a class 114 // since-cxx23-error@-1 {{invalid parameter type for non-member defaulted equality comparison operator; found 'E', expected class or reference to a constant class}} 115 116 struct S2 { 117 bool operator==(this int, S2) = default; 118 // since-cxx23-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'int', expected 'const cwg2547::S2 &'}} 119 }; 120 #endif 121 } // namespace cwg2547 122 123 namespace cwg2553 { // cwg2553: 18 review 2023-07-14 124 #if __cplusplus >= 202302L 125 struct B { 126 virtual void f(this B&); 127 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}} 128 static void f(this B&); 129 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a static function}} 130 virtual void g(); // #cwg2553-g 131 }; 132 struct D : B { 133 void g(this D&); 134 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}} 135 // since-cxx23-note@#cwg2553-g {{overridden virtual function is here}} 136 }; 137 #endif 138 } // namespace cwg2553 139 140 namespace cwg2554 { // cwg2554: 18 review 2021-12-10 141 #if __cplusplus >= 202302L 142 struct B { 143 virtual void f(); // #cwg2554-g 144 }; 145 146 struct D : B { 147 void f(this D&); 148 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}} 149 // since-cxx23-note@#cwg2554-g {{overridden virtual function is here}} 150 }; 151 152 struct D2 : B { 153 void f(this B&); 154 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}} 155 // since-cxx23-note@#cwg2554-g {{overridden virtual function is here}} 156 }; 157 struct T {}; 158 struct D3 : B { 159 void f(this T&); 160 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}} 161 // since-cxx23-note@#cwg2554-g {{overridden virtual function is here}} 162 }; 163 #endif 164 } // namespace cwg2554 165 166 namespace cwg2561 { // cwg2561: no 167 #if __cplusplus >= 202302L 168 struct C { 169 constexpr C(auto) { } 170 }; 171 void foo() { 172 constexpr auto b = [](this C) { return 1; }; 173 // FIXME: closure type shouldn't have a conversion function to function 174 // pointer, because explicit object parameter is present. 175 constexpr int (*fp)(C) = b; 176 static_assert(fp(1) == 1); 177 static_assert((&decltype(b)::operator())(1) == 1); 178 } 179 #endif 180 } // namespace cwg2561 181 182 namespace cwg2565 { // cwg2565: 16 open 2023-06-07 183 #if __cplusplus >= 202002L 184 template<typename T> 185 concept C = requires (typename T::type x) { 186 x + 1; 187 }; 188 static_assert(!C<int>); 189 190 // Variant of this as reported in GH57487. 191 template<bool B> struct bool_constant 192 { static constexpr bool value = B; }; 193 194 template<typename T> 195 using is_referenceable 196 = bool_constant<requires (T&) { true; }>; 197 198 static_assert(!is_referenceable<void>::value); 199 static_assert(is_referenceable<int>::value); 200 201 template<typename T, typename U> 202 concept TwoParams = requires (T *a, U b){ true;}; // #cwg2565-TPC 203 204 template<typename T, typename U> 205 requires TwoParams<T, U> // #cwg2565-TPSREQ 206 struct TwoParamsStruct{}; 207 208 using TPSU = TwoParamsStruct<void, void>; 209 // since-cxx20-error@-1 {{constraints not satisfied for class template 'TwoParamsStruct' [with T = void, U = void]}} 210 // since-cxx20-note@#cwg2565-TPSREQ {{because 'TwoParams<void, void>' evaluated to false}} 211 // since-cxx20-note@#cwg2565-TPC {{because 'b' would be invalid: argument may not have 'void' type}} 212 213 template<typename T, typename ...U> 214 concept Variadic = requires (U* ... a, T b){ true;}; // #cwg2565-VC 215 216 template<typename T, typename ...U> 217 requires Variadic<T, U...> // #cwg2565-VSREQ 218 struct VariadicStruct{}; 219 220 using VSU = VariadicStruct<void, int, char, double>; 221 // since-cxx20-error@-1 {{constraints not satisfied for class template 'VariadicStruct' [with T = void, U = <int, char, double>]}} 222 // since-cxx20-note@#cwg2565-VSREQ {{because 'Variadic<void, int, char, double>' evaluated to false}} 223 // since-cxx20-note@#cwg2565-VC {{because 'b' would be invalid: argument may not have 'void' type}} 224 225 template<typename T> 226 concept ErrorRequires = requires (ErrorRequires auto x) { 227 // since-cxx20-error@-1 {{a concept definition cannot refer to itself}} 228 // since-cxx20-note@-2 {{declared here}} 229 // since-cxx20-error@-3 {{'auto' not allowed in requires expression parameter}} 230 x; 231 }; 232 static_assert(ErrorRequires<int>); 233 // since-cxx20-error@-1 {{static assertion failed}} 234 // since-cxx20-note@-2 {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} 235 236 template<typename T> 237 concept NestedErrorInRequires = requires (T x) { // #cwg2565-NEIR 238 requires requires (NestedErrorInRequires auto y) { 239 // since-cxx20-error@-1 {{a concept definition cannot refer to itself}} 240 // since-cxx20-note@#cwg2565-NEIR {{declared here}} 241 // since-cxx20-error@-3 {{'auto' not allowed in requires expression parameter}} 242 y; 243 }; 244 }; 245 static_assert(NestedErrorInRequires<int>); 246 // since-cxx20-error@-1 {{static assertion failed}} 247 // since-cxx20-note@-2 {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} 248 249 #endif 250 } // namespace cwg2565 251 252 namespace cwg2583 { // cwg2583: 19 253 #if __cplusplus >= 201103L 254 struct A { 255 int i; 256 char c; 257 }; 258 259 struct B { 260 int i; 261 alignas(8) char c; 262 }; 263 264 union U { 265 A a; 266 B b; 267 }; 268 269 union V { 270 A a; 271 alignas(64) B b; 272 }; 273 274 static_assert(!__is_layout_compatible(A, B), ""); 275 static_assert(__is_layout_compatible(U, V), ""); 276 #endif 277 } // namespace cwg2583 278 279 namespace cwg2586 { // cwg2586: 20 280 #if __cplusplus >= 202302L 281 struct X { 282 X& operator=(this X&, const X&) = default; 283 X& operator=(this X&, X&) = default; 284 X& operator=(this X&&, X&&) = default; 285 // FIXME: The notes could be clearer on *how* the type differs 286 // e.g., "if an explicit object parameter is used it must be of type reference to 'X'" 287 X& operator=(this int, const X&) = default; 288 // since-cxx23-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}} 289 // since-cxx23-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}} 290 X& operator=(this X, const X&) = default; 291 // since-cxx23-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}} 292 // since-cxx23-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}} 293 }; 294 struct Y { 295 void operator=(this int, const Y&); // This is copy constructor, suppresses implicit declaration 296 }; 297 static_assert([]<typename T = Y>{ 298 return !requires(T t, const T& ct) { t = ct; }; 299 }()); 300 301 struct Z { 302 bool operator==(this const Z&, const Z&) = default; 303 bool operator==(this Z, Z) = default; 304 bool operator==(this Z, const Z&) = default; 305 // since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'Z' vs 'const Z &')}} 306 bool operator==(this const Z&, Z) = default; 307 // since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'const Z &' vs 'Z')}} 308 bool operator==(this int, Z) = default; 309 // since-cxx23-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'int', expected 'const cwg2586::Z &'}} 310 }; 311 #endif 312 } // namespace cwg2586 313 314 namespace cwg2598 { // cwg2598: 18 315 #if __cplusplus >= 201103L 316 struct NonLiteral { 317 NonLiteral(); 318 }; 319 320 struct anonymous1 { 321 union {} a; 322 }; 323 static_assert(__is_literal(anonymous1), ""); 324 325 struct anonymous2 { 326 union { char c; }; 327 }; 328 static_assert(__is_literal(anonymous2), ""); 329 330 struct anonymous3 { 331 union { char c; NonLiteral NL; }; 332 }; 333 static_assert(__is_literal(anonymous3), ""); 334 335 struct anonymous4 { 336 union { NonLiteral NL; }; 337 }; 338 static_assert(!__is_literal(anonymous4), ""); 339 340 union empty {}; 341 static_assert(__is_literal(empty), ""); 342 343 union union1 { char c; }; 344 static_assert(__is_literal(union1), ""); 345 346 union union2 { char c; NonLiteral NL;}; 347 static_assert(__is_literal(union2), ""); 348 349 union union3 { NonLiteral NL;}; 350 static_assert(!__is_literal(union3), ""); 351 352 union union4 { union4(); }; 353 static_assert(!__is_literal(union4), ""); 354 355 union union5 { static NonLiteral NL; }; 356 static_assert(__is_literal(union5), ""); 357 358 struct Literal { constexpr Literal() {} }; 359 union union6 { NonLiteral NL; Literal L; }; 360 static_assert(__is_literal(union6), ""); 361 362 #if __cplusplus >= 202003L 363 struct A { A(); }; 364 union U { 365 A a; 366 constexpr U() {} 367 constexpr ~U() {} 368 }; 369 static_assert(!__is_literal(U), ""); 370 #endif 371 #endif 372 } // namespace cwg2598 373