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 | |