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