MicrosoftCompatibility.cpp
10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions -fms-compatibility-version=19.00
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -Wmicrosoft -verify -fms-compatibility -fexceptions -fcxx-exceptions -fms-compatibility-version=18.00
#if defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT
char16_t x;
char32_t y;
#else
typedef unsigned short char16_t;
typedef unsigned int char32_t;
#endif
_Atomic(int) z;
template <typename T>
struct _Atomic {
_Atomic() {}
~_Atomic() {}
};
template <typename T>
struct atomic : _Atomic<T> {
typedef _Atomic<T> TheBase;
TheBase field;
};
_Atomic(int) alpha;
typename decltype(3) a; // expected-warning {{expected a qualified name after 'typename'}}
namespace ms_conversion_rules {
void f(float a);
void f(int a);
void test()
{
long a = 0;
f((long)0);
f(a);
}
}
namespace ms_predefined_types {
// ::type_info is a built-in forward class declaration.
void f(const type_info &a);
void f(size_t);
}
namespace ms_protected_scope {
struct C { C(); };
int jump_over_variable_init(bool b) {
if (b)
goto foo; // expected-warning {{jump from this goto statement to its label is a Microsoft extension}}
C c; // expected-note {{jump bypasses variable initialization}}
foo:
return 1;
}
struct Y {
~Y();
};
void jump_over_var_with_dtor() {
goto end; // expected-warning{{jump from this goto statement to its label is a Microsoft extension}}
Y y; // expected-note {{jump bypasses variable with a non-trivial destructor}}
end:
;
}
void jump_over_variable_case(int c) {
switch (c) {
case 0:
int x = 56; // expected-note {{jump bypasses variable initialization}}
case 1: // expected-error {{cannot jump}}
x = 10;
}
}
void exception_jump() {
goto l2; // expected-error {{cannot jump}}
try { // expected-note {{jump bypasses initialization of try block}}
l2: ;
} catch(int) {
}
}
int jump_over_indirect_goto() {
static void *ps[] = { &&a0 };
goto *&&a0; // expected-warning {{jump from this goto statement to its label is a Microsoft extension}}
int a = 3; // expected-note {{jump bypasses variable initialization}}
a0:
return 0;
}
}
namespace PR11826 {
struct pair {
pair(int v) { }
#if _MSC_VER >= 1900
void operator=(pair&& rhs) { } // expected-note {{copy constructor is implicitly deleted because 'pair' has a user-declared move assignment operator}}
#else
void operator=(pair&& rhs) { }
#endif
};
void f() {
pair p0(3);
#if _MSC_VER >= 1900
pair p = p0; // expected-error {{call to implicitly-deleted copy constructor of 'PR11826::pair'}}
#else
pair p = p0;
#endif
}
}
namespace PR11826_for_symmetry {
struct pair {
pair(int v) { }
#if _MSC_VER >= 1900
pair(pair&& rhs) { } // expected-note {{copy assignment operator is implicitly deleted because 'pair' has a user-declared move constructor}}
#else
pair(pair&& rhs) { }
#endif
};
void f() {
pair p0(3);
pair p(4);
#if _MSC_VER >= 1900
p = p0; // expected-error {{object of type 'PR11826_for_symmetry::pair' cannot be assigned because its copy assignment operator is implicitly deleted}}
#else
p = p0;
#endif
}
}
namespace ms_using_declaration_bug {
class A {
public:
int f();
};
class B : public A {
private:
using A::f;
void g() {
f(); // no diagnostic
}
};
class C : public B {
private:
using B::f; // expected-warning {{using declaration referring to inaccessible member 'ms_using_declaration_bug::B::f' (which refers to accessible member 'ms_using_declaration_bug::A::f') is a Microsoft compatibility extension}}
};
}
namespace using_tag_redeclaration
{
struct S;
namespace N {
using ::using_tag_redeclaration::S;
struct S {}; // expected-note {{previous definition is here}}
}
void f() {
N::S s1;
S s2;
}
void g() {
struct S; // expected-note {{forward declaration of 'S'}}
S s3; // expected-error {{variable has incomplete type 'S'}}
}
void h() {
using ::using_tag_redeclaration::S;
struct S {}; // expected-error {{redefinition of 'S'}}
}
}
namespace MissingTypename {
template<class T> class A {
public:
typedef int TYPE;
};
template<class T> class B {
public:
typedef int TYPE;
};
template<class T, class U>
class C : private A<T>, public B<U> {
public:
typedef A<T> Base1;
typedef B<U> Base2;
typedef A<U> Base3;
A<T>::TYPE a1; // expected-warning {{missing 'typename' prior to dependent type name}}
Base1::TYPE a2; // expected-warning {{missing 'typename' prior to dependent type name}}
B<U>::TYPE a3; // expected-warning {{missing 'typename' prior to dependent type name}}
Base2::TYPE a4; // expected-warning {{missing 'typename' prior to dependent type name}}
A<U>::TYPE a5; // expected-error {{missing 'typename' prior to dependent type name}}
Base3::TYPE a6; // expected-error {{missing 'typename' prior to dependent type name}}
};
class D {
public:
typedef int Type;
};
template <class T>
void function_missing_typename(const T::Type param)// expected-warning {{missing 'typename' prior to dependent type name}}
{
const T::Type var = 2; // expected-warning {{missing 'typename' prior to dependent type name}}
}
template void function_missing_typename<D>(const D::Type param);
}
//MSVC allows forward enum declaration
enum ENUM; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
ENUM *var = 0;
ENUM var2 = (ENUM)3;
enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}}
enum ENUM1 { kA };
enum ENUM1; // This way round is fine.
enum ENUM2 {
ENUM2_a = (enum ENUM2) 4,
ENUM2_b = 0x9FFFFFFF, // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
ENUM2_c = 0x100000000 // expected-warning {{enumerator value is not representable in the underlying type 'int'}}
};
namespace NsEnumForwardDecl {
enum E *p; // expected-warning {{forward references to 'enum' types are a Microsoft extension}}
extern E e;
}
// Clang used to complain that NsEnumForwardDecl::E was undeclared below.
NsEnumForwardDecl::E NsEnumForwardDecl_e;
namespace NsEnumForwardDecl {
extern E e;
}
namespace PR11791 {
template<class _Ty>
void del(_Ty *_Ptr) {
_Ptr->~_Ty(); // expected-warning {{pseudo-destructors on type void are a Microsoft extension}}
}
void f() {
int* a = 0;
del((void*)a); // expected-note {{in instantiation of function template specialization}}
}
}
namespace IntToNullPtrConv {
struct Foo {
static const int ZERO = 0;
typedef void (Foo::*MemberFcnPtr)();
};
struct Bar {
const Foo::MemberFcnPtr pB;
};
Bar g_bar = { (Foo::MemberFcnPtr)Foo::ZERO };
template<int N> int *get_n() { return N; } // expected-warning {{expression which evaluates to zero treated as a null pointer constant}}
int *g_nullptr = get_n<0>(); // expected-note {{in instantiation of function template specialization}}
}
namespace signed_hex_i64 {
void f(long long);
void f(int);
void g() {
// This is an ambiguous call in standard C++.
// This calls f(long long) in Microsoft mode because LL is always signed.
f(0xffffffffffffffffLL);
f(0xffffffffffffffffi64);
}
}
typedef void (*FnPtrTy)();
void (*PR23733_1)() = static_cast<FnPtrTy>((void *)0); // expected-warning {{static_cast between pointer-to-function and pointer-to-object is a Microsoft extension}}
void (*PR23733_2)() = FnPtrTy((void *)0);
void (*PR23733_3)() = (FnPtrTy)((void *)0);
void (*PR23733_4)() = reinterpret_cast<FnPtrTy>((void *)0);
long function_prototype(int a);
long (*function_ptr)(int a);
void function_to_voidptr_conv() {
void *a1 = function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}}
void *a2 = &function_prototype; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}}
void *a3 = function_ptr; // expected-warning {{implicit conversion between pointer-to-function and pointer-to-object is a Microsoft extension}}
}
namespace member_lookup {
template<typename T>
struct ConfuseLookup {
T* m_val;
struct m_val {
static size_t ms_test;
};
};
// Microsoft mode allows explicit constructor calls
// This could confuse name lookup in cases such as this
template<typename T>
size_t ConfuseLookup<T>::m_val::ms_test
= size_t(&(char&)(reinterpret_cast<ConfuseLookup<T>*>(0)->m_val));
void instantiate() { ConfuseLookup<int>::m_val::ms_test = 1; }
}
// Microsoft doesn't validate exception specification.
namespace microsoft_exception_spec {
void foo(); // expected-note {{previous declaration}}
void foo() throw(); // expected-warning {{exception specification in declaration does not match previous declaration}}
void r6() throw(...); // expected-note {{previous declaration}}
void r6() throw(int); // expected-warning {{exception specification in declaration does not match previous declaration}}
struct Base {
virtual void f2();
virtual void f3() throw(...);
};
struct Derived : Base {
virtual void f2() throw(...);
virtual void f3();
};
class A {
virtual ~A() throw();
#if __cplusplus <= 199711L
// expected-note@-2 {{overridden virtual function is here}}
#endif
};
class B : public A {
virtual ~B();
#if __cplusplus <= 199711L
// expected-warning@-2 {{exception specification of overriding function is more lax than base version}}
#endif
};
}
namespace PR25265 {
struct S {
int fn() throw(); // expected-note {{previous declaration is here}}
};
int S::fn() { return 0; } // expected-warning {{is missing exception specification}}
}
namespace PR43265 {
template <int N> // expected-note {{template parameter is declared here}}
struct Foo {
static const int N = 42; // expected-warning {{declaration of 'N' shadows template parameter}}
};
}
namespace Inner_Outer_same_template_param_name {
template <typename T> // expected-note {{template parameter is declared here}}
struct Outmost {
template <typename T> // expected-warning {{declaration of 'T' shadows template parameter}}
struct Inner {
void f() {
T *var;
}
};
};
}