Home | History | Annotate | Download | only in Parser
      1 // RUN: %clang_cc1 %s -triple i386-pc-win32 -std=c++14 -fsyntax-only -Wno-unused-getter-return-value -Wno-unused-value -Wmicrosoft -verify -fms-extensions -fms-compatibility -fdelayed-template-parsing
      2 
      3 /* Microsoft attribute tests */
      4 [repeatable][source_annotation_attribute( Parameter|ReturnValue )]
      5 struct SA_Post{ SA_Post(); int attr; };
      6 
      7 [returnvalue:SA_Post( attr=1)]
      8 int foo1([SA_Post(attr=1)] void *param);
      9 
     10 namespace {
     11   [returnvalue:SA_Post(attr=1)]
     12   int foo2([SA_Post(attr=1)] void *param);
     13 }
     14 
     15 class T {
     16   [returnvalue:SA_Post(attr=1)]
     17   int foo3([SA_Post(attr=1)] void *param);
     18 };
     19 
     20 extern "C" {
     21   [returnvalue:SA_Post(attr=1)]
     22   int foo5([SA_Post(attr=1)] void *param);
     23 }
     24 
     25 class class_attr {
     26 public:
     27   class_attr([SA_Pre(Null=SA_No,NullTerminated=SA_Yes)]  int a)
     28   {
     29   }
     30 };
     31 
     32 
     33 
     34 void uuidof_test1()
     35 {
     36   __uuidof(0);  // expected-error {{you need to include <guiddef.h> before using the '__uuidof' operator}}
     37 }
     38 
     39 typedef struct _GUID
     40 {
     41     unsigned long  Data1;
     42     unsigned short Data2;
     43     unsigned short Data3;
     44     unsigned char  Data4[8];
     45 } GUID;
     46 
     47 struct __declspec(uuid(L"00000000-0000-0000-1234-000000000047")) uuid_attr_bad1 { };// expected-error {{'uuid' attribute requires a string}}
     48 struct __declspec(uuid(3)) uuid_attr_bad2 { };// expected-error {{'uuid' attribute requires a string}}
     49 struct __declspec(uuid("0000000-0000-0000-1234-0000500000047")) uuid_attr_bad3 { };// expected-error {{uuid attribute contains a malformed GUID}}
     50 struct __declspec(uuid("0000000-0000-0000-Z234-000000000047")) uuid_attr_bad4 { };// expected-error {{uuid attribute contains a malformed GUID}}
     51 struct __declspec(uuid("000000000000-0000-1234-000000000047")) uuid_attr_bad5 { };// expected-error {{uuid attribute contains a malformed GUID}}
     52 
     53 __declspec(uuid("000000A0-0000-0000-C000-000000000046")) int i; // expected-warning {{'uuid' attribute only applies to classes}}
     54 
     55 struct __declspec(uuid("000000A0-0000-0000-C000-000000000046"))
     56 struct_with_uuid { };
     57 struct struct_without_uuid { };
     58 
     59 struct __declspec(uuid("000000A0-0000-0000-C000-000000000049"))
     60 struct_with_uuid2;
     61 
     62 struct
     63 struct_with_uuid2 {} ;
     64 
     65 int uuid_sema_test()
     66 {
     67    struct_with_uuid var_with_uuid[1];
     68    struct_without_uuid var_without_uuid[1];
     69 
     70    __uuidof(struct_with_uuid);
     71    __uuidof(struct_with_uuid2);
     72    __uuidof(struct_without_uuid); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
     73    __uuidof(struct_with_uuid*);
     74    __uuidof(struct_without_uuid*); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
     75    __uuidof(struct_with_uuid[1]);
     76    __uuidof(struct_with_uuid*[1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
     77    __uuidof(const struct_with_uuid[1][1]);
     78    __uuidof(const struct_with_uuid*[1][1]); // expected-error {{cannot call operator __uuidof on a type with no GUID}}
     79 
     80    __uuidof(var_with_uuid);
     81    __uuidof(var_without_uuid);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
     82    __uuidof(var_with_uuid[1]);
     83    __uuidof(var_without_uuid[1]);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
     84    __uuidof(&var_with_uuid[1]);
     85    __uuidof(&var_without_uuid[1]);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
     86 
     87    __uuidof(0);
     88    __uuidof(1);// expected-error {{cannot call operator __uuidof on a type with no GUID}}
     89 }
     90 
     91 
     92 template <class T>
     93 void template_uuid()
     94 {
     95    T expr;
     96 
     97    __uuidof(T);
     98    __uuidof(expr);
     99 }
    100 
    101 
    102 template <class T, const GUID* g = &__uuidof(T)> // expected-note {{template parameter is declared here}}
    103 class COM_CLASS_TEMPLATE  { };
    104 
    105 typedef COM_CLASS_TEMPLATE<struct_with_uuid, &*&__uuidof(struct_with_uuid)> COM_TYPE_1; // expected-warning {{non-type template argument containing a dereference operation is a Microsoft extension}}
    106 typedef COM_CLASS_TEMPLATE<struct_with_uuid> COM_TYPE_2;
    107 
    108 template <class T, const GUID& g>
    109 class COM_CLASS_TEMPLATE_REF  { };
    110 typedef COM_CLASS_TEMPLATE_REF<struct_with_uuid, __uuidof(struct_with_uuid)> COM_TYPE_REF;
    111 
    112   struct late_defined_uuid;
    113   template<typename T>
    114   void test_late_defined_uuid() {
    115     __uuidof(late_defined_uuid);
    116   }
    117   struct __declspec(uuid("000000A0-0000-0000-C000-000000000049")) late_defined_uuid;
    118 
    119 COM_CLASS_TEMPLATE_REF<int, __uuidof(struct_with_uuid)> good_template_arg;
    120 
    121 COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument of type 'const _GUID' is not a constant expression}}
    122 
    123 namespace PR16911 {
    124 struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
    125 struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid2;
    126 
    127 template <typename T, typename T2>
    128 struct thing {
    129 };
    130 
    131 struct empty {};
    132 struct inher : public thing<empty, uuid2> {};
    133 
    134 struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
    135 const struct _GUID *w = &__uuidof(inher); // expected-error{{cannot call operator __uuidof on a type with no GUID}}
    136 const struct _GUID *x = &__uuidof(thing<uuid, inher>);
    137 const struct _GUID *y = &__uuidof(thing<uuid2, uuid>); // expected-error{{cannot call operator __uuidof on a type with multiple GUIDs}}
    138 thing<uuid2, uuid> thing_obj = thing<uuid2, uuid>();
    139 const struct _GUID *z = &__uuidof(thing_obj); // expected-error{{cannot call operator __uuidof on a type with multiple GUIDs}}
    140 }
    141 
    142 class CtorCall {
    143 public:
    144   CtorCall& operator=(const CtorCall& that);
    145 
    146   int a;
    147 };
    148 
    149 CtorCall& CtorCall::operator=(const CtorCall& that)
    150 {
    151     if (this != &that) {
    152         this->CtorCall::~CtorCall();
    153         this->CtorCall::CtorCall(that); // expected-warning {{explicit constructor calls are a Microsoft extension}}
    154     }
    155     return *this;
    156 }
    157 
    158 template <class A>
    159 class C1 {
    160 public:
    161   template <int B>
    162   class Iterator {
    163   };
    164 };
    165 
    166 template<class T>
    167 class C2  {
    168   typename C1<T>:: /*template*/  Iterator<0> Mypos; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
    169 };
    170 
    171 template <class T>
    172 void missing_template_keyword(){
    173   typename C1<T>:: /*template*/ Iterator<0> Mypos; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
    174 }
    175 
    176 
    177 
    178 class AAAA {
    179    typedef int D;
    180 };
    181 
    182 template <typename T>
    183 class SimpleTemplate {};
    184 
    185 template <class T>
    186 void redundant_typename() {
    187    typename T t;// expected-warning {{expected a qualified name after 'typename'}}
    188    typename AAAA a;// expected-warning {{expected a qualified name after 'typename'}}
    189 
    190    t = 3;
    191 
    192    typedef typename T* pointerT;// expected-warning {{expected a qualified name after 'typename'}}
    193    typedef typename SimpleTemplate<int> templateT;// expected-warning {{expected a qualified name after 'typename'}}
    194 
    195    pointerT pT = &t;
    196    *pT = 4;
    197 
    198    int var;
    199    int k = typename var;// expected-error {{expected a qualified name after 'typename'}}
    200 }
    201 
    202 template <typename T>
    203 struct TypenameWrongPlace {
    204   typename typedef T::D D;// expected-warning {{expected a qualified name after 'typename'}}
    205 };
    206 
    207 extern TypenameWrongPlace<AAAA> PR16925;
    208 
    209 __interface MicrosoftInterface;
    210 __interface MicrosoftInterface {
    211    void foo1() = 0; // expected-note {{overridden virtual function is here}}
    212    virtual void foo2() = 0;
    213 };
    214 
    215 __interface MicrosoftDerivedInterface : public MicrosoftInterface {
    216   void foo1(); // expected-warning {{'foo1' overrides a member function but is not marked 'override'}}
    217   void foo2() override;
    218   void foo3();
    219 };
    220 
    221 void interface_test() {
    222   MicrosoftInterface* a;
    223   a->foo1();
    224   MicrosoftDerivedInterface* b;
    225   b->foo2();
    226 }
    227 
    228 __int64 x7 = __int64(0);
    229 _int64 x8 = _int64(0);
    230 static_assert(sizeof(_int64) == 8, "");
    231 static_assert(sizeof(_int32) == 4, "");
    232 static_assert(sizeof(_int16) == 2, "");
    233 static_assert(sizeof(_int8) == 1, "");
    234 
    235 int __identifier(generic) = 3;
    236 int __identifier(int) = 4;
    237 struct __identifier(class) { __identifier(class) *__identifier(for); };
    238 __identifier(class) __identifier(struct) = { &__identifier(struct) };
    239 
    240 int __identifier for; // expected-error {{missing '(' after '__identifier'}}
    241 int __identifier(else} = __identifier(for); // expected-error {{missing ')' after identifier}} expected-note {{to match this '('}}
    242 #define identifier_weird(x) __identifier(x
    243 int k = identifier_weird(if)); // expected-error {{use of undeclared identifier 'if'}}
    244 
    245 // This is a bit weird, but the alternative tokens aren't keywords, and this
    246 // behavior matches MSVC. FIXME: Consider supporting this anyway.
    247 extern int __identifier(and) r; // expected-error {{cannot convert '&&' token to an identifier}}
    248 
    249 void f() {
    250   __identifier(() // expected-error {{cannot convert '(' token to an identifier}}
    251   __identifier(void) // expected-error {{use of undeclared identifier 'void'}}
    252   __identifier()) // expected-error {{cannot convert ')' token to an identifier}}
    253   // FIXME: We should pick a friendlier display name for this token kind.
    254   __identifier(1) // expected-error {{cannot convert <numeric_constant> token to an identifier}}
    255   __identifier(+) // expected-error {{cannot convert '+' token to an identifier}}
    256   __identifier("foo") // expected-error {{cannot convert <string_literal> token to an identifier}}
    257   __identifier(;) // expected-error {{cannot convert ';' token to an identifier}}
    258 }
    259 
    260 class inline_definition_pure_spec {
    261    virtual int f() = 0 { return 0; }// expected-warning {{function definition with pure-specifier is a Microsoft extension}}
    262    virtual int f2() = 0;
    263 };
    264 
    265 struct pure_virtual_dtor {
    266   virtual ~pure_virtual_dtor() = 0;
    267 };
    268 pure_virtual_dtor::~pure_virtual_dtor() { }
    269 
    270 struct pure_virtual_dtor_inline {
    271   virtual ~pure_virtual_dtor_inline() = 0 { }// expected-warning {{function definition with pure-specifier is a Microsoft extension}}
    272 };
    273 
    274 
    275 int main () {
    276   // Necessary to force instantiation in -fdelayed-template-parsing mode.
    277   test_late_defined_uuid<int>();
    278   redundant_typename<int>();
    279   missing_template_keyword<int>();
    280 }
    281 
    282 namespace access_protected_PTM {
    283   class A {
    284   protected:
    285     void f(); // expected-note {{must name member using the type of the current context 'access_protected_PTM::B'}}
    286   };
    287 
    288   class B : public A{
    289   public:
    290     void test_access();
    291     static void test_access_static();
    292   };
    293 
    294   void B::test_access() {
    295     &A::f; // expected-error {{'f' is a protected member of 'access_protected_PTM::A'}}
    296   }
    297 
    298   void B::test_access_static() {
    299     &A::f;
    300   }
    301 }
    302 
    303 namespace Inheritance {
    304   class __single_inheritance A;
    305   class __multiple_inheritance B;
    306   class __virtual_inheritance C;
    307 }
    308 
    309 struct StructWithProperty {
    310   __declspec(property) int V0; // expected-error {{expected '(' after 'property'}}
    311   __declspec(property()) int V1; // expected-error {{property does not specify a getter or a putter}}
    312   __declspec(property(set)) int V2; // expected-error {{putter for property must be specified as 'put', not 'set'}} expected-error {{expected '=' after 'set'}}
    313   __declspec(property(ptu)) int V3; // expected-error {{missing 'get=' or 'put='}}
    314   __declspec(property(ptu=PutV)) int V4; // expected-error {{expected 'get' or 'put' in property declaration}}
    315   __declspec(property(get)) int V5; // expected-error {{expected '=' after 'get'}}
    316   __declspec(property(get&)) int V6; // expected-error {{expected '=' after 'get'}}
    317   __declspec(property(get=)) int V7; // expected-error {{expected name of accessor method}}
    318   __declspec(property(get=GetV)) int V8; // no-warning
    319   __declspec(property(get=GetV=)) int V9; // expected-error {{expected ',' or ')' at end of property accessor list}}
    320   __declspec(property(get=GetV,)) int V10; // expected-error {{expected 'get' or 'put' in property declaration}}
    321   __declspec(property(get=GetV,put=SetV)) int V11; // no-warning
    322   __declspec(property(get=GetV,put=SetV,get=GetV)) int V12; // expected-error {{property declaration specifies 'get' accessor twice}}
    323   __declspec(property(get=GetV)) int V13 = 3; // expected-error {{property declaration cannot have an in-class initializer}}
    324 
    325   int GetV() { return 123; }
    326   void SetV(int v) {}
    327 };
    328 void TestProperty() {
    329   StructWithProperty sp;
    330   sp.V8;
    331   sp.V8 = 0; // expected-error {{no setter defined for property 'V8'}}
    332   int i = sp.V11;
    333   sp.V11 = i++;
    334   sp.V11 += 8;
    335   sp.V11++;
    336   ++sp.V11;
    337 }
    338 
    339 //expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}
    340 #define and foo
    341 
    342 struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {};
    343 
    344 typedef bool (__stdcall __stdcall *blarg)(int);
    345 
    346 void local_callconv() {
    347   bool (__stdcall *p)(int);
    348 }
    349 
    350 struct S7 {
    351 	int foo() { return 12; }
    352 	__declspec(property(get=foo) deprecated) int t; // expected-note {{'t' has been explicitly marked deprecated here}}
    353 };
    354 
    355 // Technically, this is legal (though it does nothing)
    356 __declspec() void quux( void ) {
    357   struct S7 s;
    358   int i = s.t;	// expected-warning {{'t' is deprecated}}
    359 }
    360 
    361 void *_alloca(int);
    362 
    363 void foo(void) {
    364   __declspec(align(16)) int *buffer = (int *)_alloca(9);
    365 }
    366 
    367 template <int *>
    368 struct NullptrArg {};
    369 NullptrArg<nullptr> a;
    370 
    371 // Ignored type qualifiers after comma in declarator lists
    372 typedef int ignored_quals_dummy1, const volatile __ptr32 __ptr64 __w64 __unaligned __sptr __uptr ignored_quals1; // expected-warning {{qualifiers after comma in declarator list are ignored}}
    373 typedef void(*ignored_quals_dummy2)(), __fastcall ignored_quals2; // expected-warning {{qualifiers after comma in declarator list are ignored}}
    374 typedef void(*ignored_quals_dummy3)(), __stdcall ignored_quals3; // expected-warning {{qualifiers after comma in declarator list are ignored}}
    375 typedef void(*ignored_quals_dummy4)(), __thiscall ignored_quals4; // expected-warning {{qualifiers after comma in declarator list are ignored}}
    376 typedef void(*ignored_quals_dummy5)(), __cdecl ignored_quals5; // expected-warning {{qualifiers after comma in declarator list are ignored}}
    377 typedef void(*ignored_quals_dummy6)(), __vectorcall ignored_quals6; // expected-warning {{qualifiers after comma in declarator list are ignored}}
    378 
    379 namespace {
    380 bool f(int);
    381 template <typename T>
    382 struct A {
    383   constexpr A(T t) {
    384     __assume(f(t)); // expected-warning{{the argument to '__assume' has side effects that will be discarded}}
    385   }
    386   constexpr bool g() { return false; }
    387 };
    388 constexpr A<int> h() {
    389   A<int> b(0); // expected-note {{in instantiation of member function}}
    390   return b;
    391 }
    392 static_assert(h().g() == false, "");
    393 }
    394 
    395 namespace {
    396 __declspec(align(16)) struct align_before_key1 {};
    397 __declspec(align(16)) struct align_before_key2 {} align_before_key2_var;
    398 __declspec(align(16)) struct align_before_key3 {} *align_before_key3_var;
    399 static_assert(__alignof(struct align_before_key1) == 16, "");
    400 static_assert(__alignof(struct align_before_key2) == 16, "");
    401 static_assert(__alignof(struct align_before_key3) == 16, "");
    402 }
    403 
    404 namespace PR24027 {
    405 struct S {
    406   template <typename T>
    407   S(T);
    408 } f([] {});
    409 }
    410