| 1 | // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 |
| 2 | // RUN: %clang_cc1 -std=c++98 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 |
| 3 | // RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1 |
| 4 | // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fexceptions -fcxx-exceptions -DTEST2 |
| 5 | // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3 |
| 6 | |
| 7 | #if TEST1 |
| 8 | |
| 9 | // Microsoft doesn't validate exception specification. |
| 10 | namespace microsoft_exception_spec { |
| 11 | |
| 12 | void foo(); // expected-note {{previous declaration}} |
| 13 | void foo() throw(); // expected-warning {{exception specification in declaration does not match previous declaration}} |
| 14 | |
| 15 | void r6() throw(...); // expected-note {{previous declaration}} |
| 16 | void r6() throw(int); // expected-warning {{exception specification in declaration does not match previous declaration}} |
| 17 | |
| 18 | struct Base { |
| 19 | virtual void f2(); |
| 20 | virtual void f3() throw(...); |
| 21 | }; |
| 22 | |
| 23 | struct Derived : Base { |
| 24 | virtual void f2() throw(...); |
| 25 | virtual void f3(); |
| 26 | }; |
| 27 | |
| 28 | class A { |
| 29 | virtual ~A() throw(); |
| 30 | #if __cplusplus <= 199711L |
| 31 | // expected-note@-2 {{overridden virtual function is here}} |
| 32 | #endif |
| 33 | }; |
| 34 | |
| 35 | class B : public A { |
| 36 | virtual ~B(); |
| 37 | #if __cplusplus <= 199711L |
| 38 | // expected-warning@-2 {{exception specification of overriding function is more lax than base version}} |
| 39 | #endif |
| 40 | }; |
| 41 | |
| 42 | } |
| 43 | |
| 44 | // MSVC allows type definition in anonymous union and struct |
| 45 | struct A |
| 46 | { |
| 47 | union |
| 48 | { |
| 49 | int a; |
| 50 | struct B // expected-warning {{types declared in an anonymous union are a Microsoft extension}} |
| 51 | { |
| 52 | int c; |
| 53 | } d; |
| 54 | |
| 55 | union C // expected-warning {{types declared in an anonymous union are a Microsoft extension}} |
| 56 | { |
| 57 | int e; |
| 58 | int ee; |
| 59 | } f; |
| 60 | |
| 61 | typedef int D; // expected-warning {{types declared in an anonymous union are a Microsoft extension}} |
| 62 | struct F; // expected-warning {{types declared in an anonymous union are a Microsoft extension}} |
| 63 | }; |
| 64 | |
| 65 | struct |
| 66 | { |
| 67 | int a2; |
| 68 | |
| 69 | struct B2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} |
| 70 | { |
| 71 | int c2; |
| 72 | } d2; |
| 73 | |
| 74 | union C2 // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} |
| 75 | { |
| 76 | int e2; |
| 77 | int ee2; |
| 78 | } f2; |
| 79 | |
| 80 | typedef int D2; // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} |
| 81 | struct F2; // expected-warning {{types declared in an anonymous struct are a Microsoft extension}} |
| 82 | }; |
| 83 | }; |
| 84 | |
| 85 | // __stdcall handling |
| 86 | struct M { |
| 87 | int __stdcall addP(); |
| 88 | float __stdcall subtractP(); |
| 89 | }; |
| 90 | |
| 91 | // __unaligned handling |
| 92 | typedef char __unaligned *aligned_type; |
| 93 | typedef struct UnalignedTag { int f; } __unaligned *aligned_type2; |
| 94 | typedef char __unaligned aligned_type3; |
| 95 | |
| 96 | struct aligned_type4 { |
| 97 | int i; |
| 98 | }; |
| 99 | |
| 100 | __unaligned int aligned_type4::*p1_aligned_type4 = &aligned_type4::i; |
| 101 | int aligned_type4::* __unaligned p2_aligned_type4 = &aligned_type4::i; |
| 102 | __unaligned int aligned_type4::* __unaligned p3_aligned_type4 = &aligned_type4::i; |
| 103 | void (aligned_type4::*__unaligned p4_aligned_type4)(); |
| 104 | |
| 105 | // Check that __unaligned qualifier can be used for overloading |
| 106 | void foo_unaligned(int *arg) {} |
| 107 | void foo_unaligned(__unaligned int *arg) {} |
| 108 | void foo_unaligned(int arg) {} // expected-note {{previous definition is here}} |
| 109 | void foo_unaligned(__unaligned int arg) {} // expected-error {{redefinition of 'foo_unaligned'}} |
| 110 | class A_unaligned {}; |
| 111 | class B_unaligned : public A_unaligned {}; |
| 112 | int foo_unaligned(__unaligned A_unaligned *arg) { return 0; } |
| 113 | void *foo_unaligned(B_unaligned *arg) { return 0; } |
| 114 | |
| 115 | void test_unaligned() { |
| 116 | int *p1 = 0; |
| 117 | foo_unaligned(p1); |
| 118 | |
| 119 | __unaligned int *p2 = 0; |
| 120 | foo_unaligned(p2); |
| 121 | |
| 122 | __unaligned B_unaligned *p3 = 0; |
| 123 | int p4 = foo_unaligned(p3); |
| 124 | |
| 125 | B_unaligned *p5 = p3; // expected-error {{cannot initialize a variable of type 'B_unaligned *' with an lvalue of type '__unaligned B_unaligned *'}} |
| 126 | |
| 127 | __unaligned B_unaligned *p6 = p3; |
| 128 | |
| 129 | p1_aligned_type4 = p2_aligned_type4; |
| 130 | p2_aligned_type4 = p1_aligned_type4; // expected-error {{assigning to 'int aligned_type4::*' from incompatible type '__unaligned int aligned_type4::*'}} |
| 131 | p3_aligned_type4 = p1_aligned_type4; |
| 132 | |
| 133 | __unaligned int a[10]; |
| 134 | int *b = a; // expected-error {{cannot initialize a variable of type 'int *' with an lvalue of type '__unaligned int [10]'}} |
| 135 | } |
| 136 | |
| 137 | // Test from PR27367 |
| 138 | // We should accept assignment of an __unaligned pointer to a non-__unaligned |
| 139 | // pointer to void |
| 140 | typedef struct _ITEMIDLIST { int i; } ITEMIDLIST; |
| 141 | typedef ITEMIDLIST __unaligned *LPITEMIDLIST; |
| 142 | extern "C" __declspec(dllimport) void __stdcall CoTaskMemFree(void* pv); |
| 143 | __inline void FreeIDListArray(LPITEMIDLIST *ppidls) { |
| 144 | CoTaskMemFree(*ppidls); |
| 145 | __unaligned int *x = 0; |
| 146 | void *y = x; |
| 147 | } |
| 148 | |
| 149 | // Test from PR27666 |
| 150 | // We should accept type conversion of __unaligned to non-__unaligned references |
| 151 | typedef struct in_addr { |
| 152 | public: |
| 153 | in_addr(in_addr &a) {} // expected-note {{candidate constructor not viable: no known conversion from '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to 'in_addr &' for 1st argument; dereference the argument with *}} |
| 154 | in_addr(in_addr *a) {} // expected-note {{candidate constructor not viable: 1st argument ('__unaligned IN_ADDR *' (aka '__unaligned in_addr *')) would lose __unaligned qualifier}} |
| 155 | } IN_ADDR; |
| 156 | |
| 157 | void f(IN_ADDR __unaligned *a) { |
| 158 | IN_ADDR local_addr = *a; |
| 159 | IN_ADDR local_addr2 = a; // expected-error {{no viable conversion from '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to 'IN_ADDR' (aka 'in_addr')}} |
| 160 | } |
| 161 | |
| 162 | template<typename T> void h1(T (__stdcall M::* const )()) { } |
| 163 | |
| 164 | void m1() { |
| 165 | h1<int>(&M::addP); |
| 166 | h1(&M::subtractP); |
| 167 | } |
| 168 | |
| 169 | |
| 170 | namespace signed_hex_i64 { |
| 171 | void f(long long); // expected-note {{candidate function}} |
| 172 | void f(int); // expected-note {{candidate function}} |
| 173 | void g() { |
| 174 | // This used to be controlled by -fms-extensions, but it is now under |
| 175 | // -fms-compatibility. |
| 176 | f(0xffffffffffffffffLL); // expected-error {{call to 'f' is ambiguous}} |
| 177 | f(0xffffffffffffffffi64); |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | // Enumeration types with a fixed underlying type. |
| 182 | const int seventeen = 17; |
| 183 | typedef int Int; |
| 184 | |
| 185 | struct X0 { |
| 186 | enum E1 : Int { SomeOtherValue } field; |
| 187 | #if __cplusplus <= 199711L |
| 188 | // expected-warning@-2 {{enumeration types with a fixed underlying type are a C++11 extension}} |
| 189 | #endif |
| 190 | |
| 191 | enum E1 : seventeen; |
| 192 | }; |
| 193 | |
| 194 | #if __cplusplus <= 199711L |
| 195 | // expected-warning@+2 {{enumeration types with a fixed underlying type are a C++11 extension}} |
| 196 | #endif |
| 197 | enum : long long { |
| 198 | SomeValue = 0x100000000 |
| 199 | }; |
| 200 | |
| 201 | |
| 202 | class AAA { |
| 203 | __declspec(dllimport) void f(void) { } |
| 204 | void f2(void); // expected-note{{previous declaration is here}} |
| 205 | }; |
| 206 | |
| 207 | __declspec(dllimport) void AAA::f2(void) { // expected-error{{dllimport cannot be applied to non-inline function definition}} |
| 208 | // expected-error@-1{{redeclaration of 'AAA::f2' cannot add 'dllimport' attribute}} |
| 209 | |
| 210 | } |
| 211 | |
| 212 | |
| 213 | |
| 214 | template <class T> |
| 215 | class BB { |
| 216 | public: |
| 217 | void f(int g = 10 ); // expected-note {{previous definition is here}} |
| 218 | }; |
| 219 | |
| 220 | template <class T> |
| 221 | void BB<T>::f(int g = 0) { } // expected-warning {{redefinition of default argument}} |
| 222 | |
| 223 | |
| 224 | |
| 225 | extern void static_func(); |
| 226 | void static_func(); // expected-note {{previous declaration is here}} |
| 227 | |
| 228 | |
| 229 | static void static_func() // expected-warning {{redeclaring non-static 'static_func' as static is a Microsoft extension}} |
| 230 | { |
| 231 | |
| 232 | } |
| 233 | |
| 234 | extern const int static_var; // expected-note {{previous declaration is here}} |
| 235 | static const int static_var = 3; // expected-warning {{redeclaring non-static 'static_var' as static is a Microsoft extension}} |
| 236 | |
| 237 | void pointer_to_integral_type_conv(char* ptr) { |
| 238 | char ch = (char)ptr; |
| 239 | short sh = (short)ptr; |
| 240 | ch = (char)ptr; |
| 241 | sh = (short)ptr; |
| 242 | |
| 243 | // These are valid C++. |
| 244 | bool b = (bool)ptr; |
| 245 | b = static_cast<bool>(ptr); |
| 246 | |
| 247 | // This is bad. |
| 248 | b = reinterpret_cast<bool>(ptr); // expected-error {{cast from pointer to smaller type 'bool' loses information}} |
| 249 | } |
| 250 | |
| 251 | struct PR11150 { |
| 252 | class X { |
| 253 | virtual void f() = 0; |
| 254 | }; |
| 255 | |
| 256 | int array[__is_abstract(X)? 1 : -1]; |
| 257 | }; |
| 258 | |
| 259 | void f() { int __except = 0; } |
| 260 | |
| 261 | void ::f(); // expected-warning{{extra qualification on member 'f'}} |
| 262 | |
| 263 | class C { |
| 264 | C::C(); // expected-warning{{extra qualification on member 'C'}} |
| 265 | }; |
| 266 | |
| 267 | struct StructWithProperty { |
| 268 | __declspec(property(get=GetV)) int V1; |
| 269 | __declspec(property(put=SetV)) int V2; |
| 270 | __declspec(property(get=GetV, put=SetV_NotExist)) int V3; |
| 271 | __declspec(property(get=GetV_NotExist, put=SetV)) int V4; |
| 272 | __declspec(property(get=GetV, put=SetV)) int V5; |
| 273 | |
| 274 | int GetV() { return 123; } |
| 275 | void SetV(int i) {} |
| 276 | }; |
| 277 | void TestProperty() { |
| 278 | StructWithProperty sp; |
| 279 | int i = sp.V2; // expected-error{{no getter defined for property 'V2'}} |
| 280 | sp.V1 = 12; // expected-error{{no setter defined for property 'V1'}} |
| 281 | int j = sp.V4; // expected-error{{no member named 'GetV_NotExist' in 'StructWithProperty'}} expected-error{{cannot find suitable getter for property 'V4'}} |
| 282 | sp.V3 = 14; // expected-error{{no member named 'SetV_NotExist' in 'StructWithProperty'}} expected-error{{cannot find suitable setter for property 'V3'}} |
| 283 | int k = sp.V5; |
| 284 | sp.V5 = k++; |
| 285 | } |
| 286 | |
| 287 | /* 4 tests for PseudoObject, begin */ |
| 288 | struct SP1 |
| 289 | { |
| 290 | bool operator()() { return true; } |
| 291 | }; |
| 292 | struct SP2 |
| 293 | { |
| 294 | __declspec(property(get=GetV)) SP1 V; |
| 295 | SP1 GetV() { return SP1(); } |
| 296 | }; |
| 297 | void TestSP2() { |
| 298 | SP2 sp2; |
| 299 | bool b = sp2.V(); |
| 300 | } |
| 301 | |
| 302 | struct SP3 { |
| 303 | template <class T> |
| 304 | void f(T t) {} |
| 305 | }; |
| 306 | template <class T> |
| 307 | struct SP4 |
| 308 | { |
| 309 | __declspec(property(get=GetV)) int V; |
| 310 | int GetV() { return 123; } |
| 311 | void f() { SP3 s2; s2.f(V); } |
| 312 | }; |
| 313 | void TestSP4() { |
| 314 | SP4<int> s; |
| 315 | s.f(); |
| 316 | } |
| 317 | |
| 318 | template <class T> |
| 319 | struct SP5 |
| 320 | { |
| 321 | __declspec(property(get=GetV)) T V; |
| 322 | int GetV() { return 123; } |
| 323 | void f() { int *p = new int[V]; } |
| 324 | }; |
| 325 | |
| 326 | template <class T> |
| 327 | struct SP6 |
| 328 | { |
| 329 | public: |
| 330 | __declspec(property(get=GetV)) T V; |
| 331 | T GetV() { return 123; } |
| 332 | void f() { int t = V; } |
| 333 | }; |
| 334 | void TestSP6() { |
| 335 | SP6<int> c; |
| 336 | c.f(); |
| 337 | } |
| 338 | /* 4 tests for PseudoObject, end */ |
| 339 | |
| 340 | // Property access: explicit, implicit, with Qualifier |
| 341 | struct SP7 { |
| 342 | __declspec(property(get=GetV, put=SetV)) int V; |
| 343 | int GetV() { return 123; } |
| 344 | void SetV(int v) {} |
| 345 | |
| 346 | void ImplicitAccess() { int i = V; V = i; } |
| 347 | void ExplicitAccess() { int i = this->V; this->V = i; } |
| 348 | }; |
| 349 | struct SP8: public SP7 { |
| 350 | void AccessWithQualifier() { int i = SP7::V; SP7::V = i; } |
| 351 | }; |
| 352 | |
| 353 | // Property usage |
| 354 | template <class T> |
| 355 | struct SP9 { |
| 356 | __declspec(property(get=GetV, put=SetV)) T V; |
| 357 | T GetV() { return 0; } |
| 358 | void SetV(T v) {} |
| 359 | bool f() { V = this->V; return V < this->V; } |
| 360 | void g() { V++; } |
| 361 | void h() { V*=2; } |
| 362 | }; |
| 363 | struct SP10 { |
| 364 | SP10(int v) {} |
| 365 | bool operator<(const SP10& v) { return true; } |
| 366 | SP10 operator*(int v) { return *this; } |
| 367 | SP10 operator+(int v) { return *this; } |
| 368 | SP10& operator=(const SP10& v) { return *this; } |
| 369 | }; |
| 370 | void TestSP9() { |
| 371 | SP9<int> c; |
| 372 | int i = c.V; // Decl initializer |
| 373 | i = c.V; // Binary op operand |
| 374 | c.SetV(c.V); // CallExpr arg |
| 375 | int *p = new int[c.V + 1]; // Array size |
| 376 | p[c.V] = 1; // Array index |
| 377 | |
| 378 | c.V = 123; // Setter |
| 379 | |
| 380 | c.V++; // Unary op operand |
| 381 | c.V *= 2; // Unary op operand |
| 382 | |
| 383 | SP9<int*> c2; |
| 384 | c2.V[0] = 123; // Array |
| 385 | |
| 386 | SP9<SP10> c3; |
| 387 | c3.f(); // Overloaded binary op operand |
| 388 | c3.g(); // Overloaded incdec op operand |
| 389 | c3.h(); // Overloaded unary op operand |
| 390 | } |
| 391 | |
| 392 | union u { |
| 393 | int *i1; |
| 394 | int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}} |
| 395 | }; |
| 396 | |
| 397 | // Property getter using reference. |
| 398 | struct SP11 { |
| 399 | __declspec(property(get=GetV)) int V; |
| 400 | int _v; |
| 401 | int& GetV() { return _v; } |
| 402 | void UseV(); |
| 403 | void TakePtr(int *) {} |
| 404 | void TakeRef(int &) {} |
| 405 | void TakeVal(int) {} |
| 406 | }; |
| 407 | |
| 408 | void SP11::UseV() { |
| 409 | TakePtr(&V); |
| 410 | TakeRef(V); |
| 411 | TakeVal(V); |
| 412 | } |
| 413 | |
| 414 | struct StructWithUnnamedMember { |
| 415 | __declspec(property(get=GetV)) int : 10; // expected-error {{anonymous property is not supported}} |
| 416 | }; |
| 417 | |
| 418 | struct MSPropertyClass { |
| 419 | int get() { return 42; } |
| 420 | int __declspec(property(get = get)) n; |
| 421 | }; |
| 422 | |
| 423 | int *f(MSPropertyClass &x) { |
| 424 | return &x.n; // expected-error {{address of property expression requested}} |
| 425 | } |
| 426 | int MSPropertyClass::*g() { |
| 427 | return &MSPropertyClass::n; // expected-error {{address of property expression requested}} |
| 428 | } |
| 429 | |
| 430 | namespace rdar14250378 { |
| 431 | class Bar {}; |
| 432 | |
| 433 | namespace NyNamespace { |
| 434 | class Foo { |
| 435 | public: |
| 436 | Bar* EnsureBar(); |
| 437 | }; |
| 438 | |
| 439 | class Baz : public Foo { |
| 440 | public: |
| 441 | friend class Bar; |
| 442 | }; |
| 443 | |
| 444 | Bar* Foo::EnsureBar() { |
| 445 | return 0; |
| 446 | } |
| 447 | } |
| 448 | } |
| 449 | |
| 450 | // expected-error@+1 {{'sealed' keyword not permitted with interface types}} |
| 451 | __interface InterfaceWithSealed sealed { |
| 452 | }; |
| 453 | |
| 454 | struct SomeBase { |
| 455 | virtual void OverrideMe(); |
| 456 | |
| 457 | // expected-note@+2 {{overridden virtual function is here}} |
| 458 | // expected-warning@+1 {{'sealed' keyword is a Microsoft extension}} |
| 459 | virtual void SealedFunction() sealed; // expected-note {{overridden virtual function is here}} |
| 460 | }; |
| 461 | |
| 462 | // expected-note@+2 {{'SealedType' declared here}} |
| 463 | // expected-warning@+1 {{'sealed' keyword is a Microsoft extension}} |
| 464 | struct SealedType sealed : SomeBase { |
| 465 | // expected-error@+2 {{declaration of 'SealedFunction' overrides a 'sealed' function}} |
| 466 | // FIXME. warning can be suppressed if we're also issuing error for overriding a 'final' function. |
| 467 | virtual void SealedFunction(); // expected-warning {{'SealedFunction' overrides a member function but is not marked 'override'}} |
| 468 | |
| 469 | #if __cplusplus <= 199711L |
| 470 | // expected-warning@+2 {{'override' keyword is a C++11 extension}} |
| 471 | #endif |
| 472 | virtual void OverrideMe() override; |
| 473 | }; |
| 474 | |
| 475 | // expected-error@+1 {{base 'SealedType' is marked 'sealed'}} |
| 476 | struct InheritFromSealed : SealedType {}; |
| 477 | |
| 478 | void AfterClassBody() { |
| 479 | // expected-warning@+1 {{attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration}} |
| 480 | struct D {} __declspec(deprecated); |
| 481 | |
| 482 | struct __declspec(align(4)) S {} __declspec(align(8)) s1; |
| 483 | S s2; |
| 484 | _Static_assert(__alignof(S) == 4, ""); |
| 485 | _Static_assert(__alignof(s1) == 8, ""); |
| 486 | _Static_assert(__alignof(s2) == 4, ""); |
| 487 | } |
| 488 | |
| 489 | namespace PR24246 { |
| 490 | template <typename TX> struct A { |
| 491 | template <bool> struct largest_type_select; |
| 492 | template <> struct largest_type_select<false> { |
| 493 | blah x; // expected-error {{unknown type name 'blah'}} |
| 494 | }; |
| 495 | }; |
| 496 | } |
| 497 | |
| 498 | namespace PR25265 { |
| 499 | struct S { |
| 500 | int fn() throw(); // expected-note {{previous declaration is here}} |
| 501 | }; |
| 502 | |
| 503 | int S::fn() { return 0; } // expected-warning {{is missing exception specification}} |
| 504 | } |
| 505 | |
| 506 | class PR34109_class { |
| 507 | PR34109_class() {} |
| 508 | virtual ~PR34109_class() {} |
| 509 | }; |
| 510 | |
| 511 | void operator delete(void *) throw(); |
| 512 | // expected-note@-1 {{previous declaration is here}} |
| 513 | __declspec(dllexport) void operator delete(void *) throw(); |
| 514 | // expected-error@-1 {{redeclaration of 'operator delete' cannot add 'dllexport' attribute}} |
| 515 | |
| 516 | void PR34109(int* a) { |
| 517 | delete a; |
| 518 | } |
| 519 | |
| 520 | #elif TEST2 |
| 521 | |
| 522 | // Check that __unaligned is not recognized if MS extensions are not enabled |
| 523 | typedef char __unaligned *aligned_type; // expected-error {{expected ';' after top level declarator}} |
| 524 | |
| 525 | #elif TEST3 |
| 526 | |
| 527 | namespace PR32750 { |
| 528 | template<typename T> struct A {}; |
| 529 | template<typename T> struct B : A<A<T>> { A<T>::C::D d; }; // expected-error {{missing 'typename' prior to dependent type name 'A<T>::C::D'}} |
| 530 | } |
| 531 | |
| 532 | #else |
| 533 | |
| 534 | #error Unknown test mode |
| 535 | |
| 536 | #endif |
| 537 | |
| 538 | |