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