Home | History | Annotate | Download | only in Parser
      1 // RUN: %clang_cc1 %s -triple i386-mingw32 -std=c++11 -fsyntax-only -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' cannot be converted to a value of type 'const GUID *' (aka 'const _GUID *')}}
    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;
    212    virtual void foo2() = 0;
    213 };
    214 
    215 __interface MicrosoftDerivedInterface : public MicrosoftInterface {
    216   void foo1();
    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 
    230 int __identifier(generic) = 3;
    231 int __identifier(int) = 4;
    232 struct __identifier(class) { __identifier(class) *__identifier(for); };
    233 __identifier(class) __identifier(struct) = { &__identifier(struct) };
    234 
    235 int __identifier for; // expected-error {{missing '(' after '__identifier'}}
    236 int __identifier(else} = __identifier(for); // expected-error {{missing ')' after identifier}} expected-note {{to match this '('}}
    237 #define identifier_weird(x) __identifier(x
    238 int k = identifier_weird(if)); // expected-error {{use of undeclared identifier 'if'}}
    239 
    240 // This is a bit weird, but the alternative tokens aren't keywords, and this
    241 // behavior matches MSVC. FIXME: Consider supporting this anyway.
    242 extern int __identifier(and) r; // expected-error {{cannot convert '&&' token to an identifier}}
    243 
    244 void f() {
    245   __identifier(() // expected-error {{cannot convert '(' token to an identifier}}
    246   __identifier(void) // expected-error {{use of undeclared identifier 'void'}}
    247   __identifier()) // expected-error {{cannot convert ')' token to an identifier}}
    248   // FIXME: We should pick a friendlier display name for this token kind.
    249   __identifier(1) // expected-error {{cannot convert <numeric_constant> token to an identifier}}
    250   __identifier(+) // expected-error {{cannot convert '+' token to an identifier}}
    251   __identifier("foo") // expected-error {{cannot convert <string_literal> token to an identifier}}
    252   __identifier(;) // expected-error {{cannot convert ';' token to an identifier}}
    253 }
    254 
    255 class inline_definition_pure_spec {
    256    virtual int f() = 0 { return 0; }// expected-warning {{function definition with pure-specifier is a Microsoft extension}}
    257    virtual int f2() = 0;
    258 };
    259 
    260 struct pure_virtual_dtor {
    261   virtual ~pure_virtual_dtor() = 0;
    262 };
    263 pure_virtual_dtor::~pure_virtual_dtor() { }
    264 
    265 struct pure_virtual_dtor_inline {
    266   virtual ~pure_virtual_dtor_inline() = 0 { }// expected-warning {{function definition with pure-specifier is a Microsoft extension}}
    267 };
    268 
    269 
    270 int main () {
    271   // Necessary to force instantiation in -fdelayed-template-parsing mode.
    272   test_late_defined_uuid<int>();
    273   redundant_typename<int>();
    274   missing_template_keyword<int>();
    275 }
    276 
    277 namespace access_protected_PTM {
    278   class A {
    279   protected:
    280     void f(); // expected-note {{must name member using the type of the current context 'access_protected_PTM::B'}}
    281   };
    282 
    283   class B : public A{
    284   public:
    285     void test_access();
    286     static void test_access_static();
    287   };
    288 
    289   void B::test_access() {
    290     &A::f; // expected-error {{'f' is a protected member of 'access_protected_PTM::A'}}
    291   }
    292 
    293   void B::test_access_static() {
    294     &A::f;
    295   }
    296 }
    297 
    298 namespace Inheritance {
    299   class __single_inheritance A;
    300   class __multiple_inheritance B;
    301   class __virtual_inheritance C;
    302 }
    303 
    304 struct StructWithProperty {
    305   __declspec(property) int V0; // expected-error {{expected '(' after 'property'}}
    306   __declspec(property()) int V1; // expected-error {{property does not specify a getter or a putter}}
    307   __declspec(property(set)) int V2; // expected-error {{putter for property must be specified as 'put', not 'set'}} expected-error {{expected '=' after 'set'}}
    308   __declspec(property(ptu)) int V3; // expected-error {{missing 'get=' or 'put='}}
    309   __declspec(property(ptu=PutV)) int V4; // expected-error {{expected 'get' or 'put' in property declaration}}
    310   __declspec(property(get)) int V5; // expected-error {{expected '=' after 'get'}}
    311   __declspec(property(get&)) int V6; // expected-error {{expected '=' after 'get'}}
    312   __declspec(property(get=)) int V7; // expected-error {{expected name of accessor method}}
    313   __declspec(property(get=GetV)) int V8; // no-warning
    314   __declspec(property(get=GetV=)) int V9; // expected-error {{expected ',' or ')' at end of property accessor list}}
    315   __declspec(property(get=GetV,)) int V10; // expected-error {{expected 'get' or 'put' in property declaration}}
    316   __declspec(property(get=GetV,put=SetV)) int V11; // no-warning
    317   __declspec(property(get=GetV,put=SetV,get=GetV)) int V12; // expected-error {{property declaration specifies 'get' accessor twice}}
    318 
    319   int GetV() { return 123; }
    320   void SetV(int v) {}
    321 };
    322 void TestProperty() {
    323   StructWithProperty sp;
    324   sp.V8;
    325   sp.V8 = 0; // expected-error {{no setter defined for property 'V8'}}
    326   int i = sp.V11;
    327   sp.V11 = i++;
    328   sp.V11 += 8;
    329   sp.V11++;
    330   ++sp.V11;
    331 }
    332 
    333 //expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}
    334 #define and foo
    335 
    336 struct __declspec(uuid("00000000-0000-0000-C000-000000000046")) __declspec(novtable) IUnknown {}; // expected-warning{{__declspec attribute 'novtable' is not supported}}
    337 
    338 typedef bool (__stdcall __stdcall *blarg)(int);
    339 
    340 void local_callconv() {
    341   bool (__stdcall *p)(int);
    342 }
    343 
    344 struct S7 {
    345 	int foo() { return 12; }
    346 	__declspec(property(get=foo) deprecated) int t; // expected-note {{'t' has been explicitly marked deprecated here}}
    347 };
    348 
    349 // Technically, this is legal (though it does nothing)
    350 __declspec() void quux( void ) {
    351   struct S7 s;
    352   int i = s.t;	// expected-warning {{'t' is deprecated}}
    353 }
    354 
    355 void *_alloca(int);
    356 
    357 void foo(void) {
    358   __declspec(align(16)) int *buffer = (int *)_alloca(9);
    359 }
    360