summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/MicrosoftCompatibility.cpp
blob: 203a810111426e2200b072a32e423387ecf0c3f8 (plain)
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
// 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}}
}