2015-07-21 06:57:31 +08:00
// 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
2010-10-13 00:46:35 +08:00
/* Microsoft attribute tests */
[ repeatable ] [ source_annotation_attribute ( Parameter | ReturnValue ) ]
struct SA_Post { SA_Post ( ) ; int attr ; } ;
2013-07-30 09:31:03 +08:00
[ returnvalue : SA_Post ( attr = 1 ) ]
2010-10-13 00:46:35 +08:00
int foo1 ( [ SA_Post ( attr = 1 ) ] void * param ) ;
namespace {
2013-07-30 09:31:03 +08:00
[ returnvalue : SA_Post ( attr = 1 ) ]
2010-10-13 00:46:35 +08:00
int foo2 ( [ SA_Post ( attr = 1 ) ] void * param ) ;
}
class T {
2013-07-30 09:31:03 +08:00
[ returnvalue : SA_Post ( attr = 1 ) ]
2010-10-13 00:46:35 +08:00
int foo3 ( [ SA_Post ( attr = 1 ) ] void * param ) ;
} ;
extern " C " {
2013-07-30 09:31:03 +08:00
[ returnvalue : SA_Post ( attr = 1 ) ]
2010-10-13 00:46:35 +08:00
int foo5 ( [ SA_Post ( attr = 1 ) ] void * param ) ;
}
2011-01-31 12:54:32 +08:00
class class_attr {
public :
class_attr ( [ SA_Pre ( Null = SA_No , NullTerminated = SA_Yes ) ] int a )
{
}
} ;
2010-10-13 00:46:35 +08:00
2010-12-20 11:51:03 +08:00
void uuidof_test1 ( )
2013-07-30 09:31:03 +08:00
{
2010-12-20 11:51:03 +08:00
__uuidof ( 0 ) ; // expected-error {{you need to include <guiddef.h> before using the '__uuidof' operator}}
}
typedef struct _GUID
{
unsigned long Data1 ;
unsigned short Data2 ;
unsigned short Data3 ;
unsigned char Data4 [ 8 ] ;
} GUID ;
2013-07-30 09:31:03 +08:00
struct __declspec ( uuid ( L " 00000000-0000-0000-1234-000000000047 " ) ) uuid_attr_bad1 { } ; // expected-error {{'uuid' attribute requires a string}}
struct __declspec ( uuid ( 3 ) ) uuid_attr_bad2 { } ; // expected-error {{'uuid' attribute requires a string}}
2010-12-20 11:51:03 +08:00
struct __declspec ( uuid ( " 0000000-0000-0000-1234-0000500000047 " ) ) uuid_attr_bad3 { } ; // expected-error {{uuid attribute contains a malformed GUID}}
struct __declspec ( uuid ( " 0000000-0000-0000-Z234-000000000047 " ) ) uuid_attr_bad4 { } ; // expected-error {{uuid attribute contains a malformed GUID}}
struct __declspec ( uuid ( " 000000000000-0000-1234-000000000047 " ) ) uuid_attr_bad5 { } ; // expected-error {{uuid attribute contains a malformed GUID}}
2013-11-25 04:58:02 +08:00
__declspec ( uuid ( " 000000A0-0000-0000-C000-000000000046 " ) ) int i ; // expected-warning {{'uuid' attribute only applies to classes}}
2010-12-20 11:51:03 +08:00
struct __declspec ( uuid ( " 000000A0-0000-0000-C000-000000000046 " ) )
struct_with_uuid { } ;
struct struct_without_uuid { } ;
2010-12-27 09:32:00 +08:00
struct __declspec ( uuid ( " 000000A0-0000-0000-C000-000000000049 " ) )
struct_with_uuid2 ;
2013-07-30 09:31:03 +08:00
struct
2010-12-27 09:32:00 +08:00
struct_with_uuid2 { } ;
2010-12-20 11:51:03 +08:00
int uuid_sema_test ( )
{
struct_with_uuid var_with_uuid [ 1 ] ;
struct_without_uuid var_without_uuid [ 1 ] ;
__uuidof ( struct_with_uuid ) ;
2010-12-27 09:32:00 +08:00
__uuidof ( struct_with_uuid2 ) ;
2010-12-20 11:51:03 +08:00
__uuidof ( struct_without_uuid ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
__uuidof ( struct_with_uuid * ) ;
__uuidof ( struct_without_uuid * ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
2013-09-27 15:57:34 +08:00
__uuidof ( struct_with_uuid [ 1 ] ) ;
__uuidof ( struct_with_uuid * [ 1 ] ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
__uuidof ( const struct_with_uuid [ 1 ] [ 1 ] ) ;
__uuidof ( const struct_with_uuid * [ 1 ] [ 1 ] ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
2010-12-20 11:51:03 +08:00
__uuidof ( var_with_uuid ) ;
__uuidof ( var_without_uuid ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
__uuidof ( var_with_uuid [ 1 ] ) ;
__uuidof ( var_without_uuid [ 1 ] ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
__uuidof ( & var_with_uuid [ 1 ] ) ;
__uuidof ( & var_without_uuid [ 1 ] ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
__uuidof ( 0 ) ;
__uuidof ( 1 ) ; // expected-error {{cannot call operator __uuidof on a type with no GUID}}
}
2010-12-27 09:32:00 +08:00
template < class T >
void template_uuid ( )
{
T expr ;
2013-07-30 09:31:03 +08:00
2010-12-27 09:32:00 +08:00
__uuidof ( T ) ;
__uuidof ( expr ) ;
}
2011-01-18 13:04:39 +08:00
2013-08-23 13:39:39 +08:00
template < class T , const GUID * g = & __uuidof ( T ) > // expected-note {{template parameter is declared here}}
2011-04-28 12:39:50 +08:00
class COM_CLASS_TEMPLATE { } ;
2013-08-23 13:39:39 +08:00
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}}
2011-04-28 12:39:50 +08:00
typedef COM_CLASS_TEMPLATE < struct_with_uuid > COM_TYPE_2 ;
2011-04-29 17:08:14 +08:00
template < class T , const GUID & g >
class COM_CLASS_TEMPLATE_REF { } ;
2012-04-16 12:08:35 +08:00
typedef COM_CLASS_TEMPLATE_REF < struct_with_uuid , __uuidof ( struct_with_uuid ) > COM_TYPE_REF ;
2011-04-28 12:39:50 +08:00
2011-05-10 08:08:32 +08:00
struct late_defined_uuid ;
template < typename T >
void test_late_defined_uuid ( ) {
__uuidof ( late_defined_uuid ) ;
}
struct __declspec ( uuid ( " 000000A0-0000-0000-C000-000000000049 " ) ) late_defined_uuid ;
2013-08-23 13:39:39 +08:00
COM_CLASS_TEMPLATE_REF < int , __uuidof ( struct_with_uuid ) > good_template_arg ;
2014-08-14 08:49:23 +08:00
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}}
2011-01-18 13:04:39 +08:00
2013-09-07 14:59:46 +08:00
namespace PR16911 {
struct __declspec ( uuid ( " {12345678-1234-1234-1234-1234567890aB} " ) ) uuid ;
struct __declspec ( uuid ( " {12345678-1234-1234-1234-1234567890aB} " ) ) uuid2 ;
template < typename T , typename T2 >
struct thing {
} ;
struct empty { } ;
struct inher : public thing < empty , uuid2 > { } ;
struct __declspec ( uuid ( " {12345678-1234-1234-1234-1234567890aB} " ) ) uuid ;
const struct _GUID * w = & __uuidof ( inher ) ; // expected-error{{cannot call operator __uuidof on a type with no GUID}}
const struct _GUID * x = & __uuidof ( thing < uuid , inher > ) ;
const struct _GUID * y = & __uuidof ( thing < uuid2 , uuid > ) ; // expected-error{{cannot call operator __uuidof on a type with multiple GUIDs}}
thing < uuid2 , uuid > thing_obj = thing < uuid2 , uuid > ( ) ;
const struct _GUID * z = & __uuidof ( thing_obj ) ; // expected-error{{cannot call operator __uuidof on a type with multiple GUIDs}}
}
2013-07-30 09:31:03 +08:00
class CtorCall {
2011-01-18 13:04:39 +08:00
public :
CtorCall & operator = ( const CtorCall & that ) ;
int a ;
} ;
CtorCall & CtorCall : : operator = ( const CtorCall & that )
{
if ( this ! = & that ) {
this - > CtorCall : : ~ CtorCall ( ) ;
this - > CtorCall : : CtorCall ( that ) ; // expected-warning {{explicit constructor calls are a Microsoft extension}}
}
return * this ;
}
2011-03-28 03:41:34 +08:00
template < class A >
class C1 {
public :
template < int B >
class Iterator {
} ;
} ;
2013-07-30 09:31:03 +08:00
2011-03-28 03:41:34 +08:00
template < class T >
class C2 {
typename C1 < T > : : /*template*/ Iterator < 0 > Mypos ; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
} ;
template < class T >
2011-05-10 08:08:32 +08:00
void missing_template_keyword ( ) {
2011-03-28 03:41:34 +08:00
typename C1 < T > : : /*template*/ Iterator < 0 > Mypos ; // expected-warning {{use 'template' keyword to treat 'Iterator' as a dependent template name}}
}
2011-04-24 19:24:13 +08:00
2013-09-04 06:36:22 +08:00
class AAAA {
typedef int D ;
} ;
2011-04-24 19:24:13 +08:00
2012-05-15 06:43:34 +08:00
template < typename T >
class SimpleTemplate { } ;
2011-04-24 19:24:13 +08:00
template < class T >
void redundant_typename ( ) {
typename T t ; // expected-warning {{expected a qualified name after 'typename'}}
typename AAAA a ; // expected-warning {{expected a qualified name after 'typename'}}
2012-05-15 06:43:34 +08:00
2011-04-24 19:24:13 +08:00
t = 3 ;
2013-07-30 09:31:03 +08:00
2012-05-15 06:43:34 +08:00
typedef typename T * pointerT ; // expected-warning {{expected a qualified name after 'typename'}}
typedef typename SimpleTemplate < int > templateT ; // expected-warning {{expected a qualified name after 'typename'}}
pointerT pT = & t ;
* pT = 4 ;
int var ;
int k = typename var ; // expected-error {{expected a qualified name after 'typename'}}
2011-04-24 19:24:13 +08:00
}
2013-09-04 06:36:22 +08:00
template < typename T >
struct TypenameWrongPlace {
typename typedef T : : D D ; // expected-warning {{expected a qualified name after 'typename'}}
} ;
extern TypenameWrongPlace < AAAA > PR16925 ;
2012-09-01 06:18:20 +08:00
__interface MicrosoftInterface ;
__interface MicrosoftInterface {
2014-10-28 03:11:51 +08:00
void foo1 ( ) = 0 ; // expected-note {{overridden virtual function is here}}
2012-09-01 06:18:20 +08:00
virtual void foo2 ( ) = 0 ;
} ;
__interface MicrosoftDerivedInterface : public MicrosoftInterface {
2014-10-28 03:11:51 +08:00
void foo1 ( ) ; // expected-warning {{'foo1' overrides a member function but is not marked 'override'}}
2012-09-01 06:18:20 +08:00
void foo2 ( ) override ;
void foo3 ( ) ;
} ;
void interface_test ( ) {
MicrosoftInterface * a ;
a - > foo1 ( ) ;
MicrosoftDerivedInterface * b ;
b - > foo2 ( ) ;
}
__int64 x7 = __int64 ( 0 ) ;
2014-08-23 00:52:57 +08:00
_int64 x8 = _int64 ( 0 ) ;
static_assert ( sizeof ( _int64 ) = = 8 , " " ) ;
static_assert ( sizeof ( _int32 ) = = 4 , " " ) ;
static_assert ( sizeof ( _int16 ) = = 2 , " " ) ;
static_assert ( sizeof ( _int8 ) = = 1 , " " ) ;
2011-05-07 04:48:22 +08:00
2011-05-08 01:47:38 +08:00
int __identifier ( generic ) = 3 ;
2014-03-15 08:06:08 +08:00
int __identifier ( int ) = 4 ;
struct __identifier ( class ) { __identifier ( class ) * __identifier ( for ) ; } ;
__identifier ( class ) __identifier ( struct ) = { & __identifier ( struct ) } ;
int __identifier for ; // expected-error {{missing '(' after '__identifier'}}
int __identifier ( else } = __identifier ( for ) ; // expected-error {{missing ')' after identifier}} expected-note {{to match this '('}}
# define identifier_weird(x) __identifier(x
int k = identifier_weird ( if ) ) ; // expected-error {{use of undeclared identifier 'if'}}
// This is a bit weird, but the alternative tokens aren't keywords, and this
// behavior matches MSVC. FIXME: Consider supporting this anyway.
extern int __identifier ( and ) r ; // expected-error {{cannot convert '&&' token to an identifier}}
void f ( ) {
__identifier ( ( ) // expected-error {{cannot convert '(' token to an identifier}}
__identifier ( void ) // expected-error {{use of undeclared identifier 'void'}}
__identifier ( ) ) // expected-error {{cannot convert ')' token to an identifier}}
// FIXME: We should pick a friendlier display name for this token kind.
__identifier ( 1 ) // expected-error {{cannot convert <numeric_constant> token to an identifier}}
__identifier ( + ) // expected-error {{cannot convert '+' token to an identifier}}
__identifier ( " foo " ) // expected-error {{cannot convert <string_literal> token to an identifier}}
__identifier ( ; ) // expected-error {{cannot convert ';' token to an identifier}}
}
2011-05-08 01:47:38 +08:00
2011-05-11 10:14:46 +08:00
class inline_definition_pure_spec {
virtual int f ( ) = 0 { return 0 ; } // expected-warning {{function definition with pure-specifier is a Microsoft extension}}
virtual int f2 ( ) = 0 ;
} ;
2013-10-09 06:45:29 +08:00
struct pure_virtual_dtor {
virtual ~ pure_virtual_dtor ( ) = 0 ;
} ;
pure_virtual_dtor : : ~ pure_virtual_dtor ( ) { }
struct pure_virtual_dtor_inline {
virtual ~ pure_virtual_dtor_inline ( ) = 0 { } // expected-warning {{function definition with pure-specifier is a Microsoft extension}}
} ;
2011-05-10 08:08:32 +08:00
int main ( ) {
// Necessary to force instantiation in -fdelayed-template-parsing mode.
2013-07-30 09:31:03 +08:00
test_late_defined_uuid < int > ( ) ;
2011-05-10 08:08:32 +08:00
redundant_typename < int > ( ) ;
missing_template_keyword < int > ( ) ;
}
2012-05-23 05:28:07 +08:00
namespace access_protected_PTM {
class A {
protected :
void f ( ) ; // expected-note {{must name member using the type of the current context 'access_protected_PTM::B'}}
} ;
2012-04-17 20:35:05 +08:00
2012-05-23 05:28:07 +08:00
class B : public A {
public :
void test_access ( ) ;
static void test_access_static ( ) ;
} ;
2012-04-17 20:35:05 +08:00
2012-05-23 05:28:07 +08:00
void B : : test_access ( ) {
& A : : f ; // expected-error {{'f' is a protected member of 'access_protected_PTM::A'}}
}
void B : : test_access_static ( ) {
& A : : f ;
}
}
2012-05-23 05:28:12 +08:00
namespace Inheritance {
class __single_inheritance A ;
class __multiple_inheritance B ;
class __virtual_inheritance C ;
}
2013-04-16 15:28:30 +08:00
struct StructWithProperty {
__declspec ( property ) int V0 ; // expected-error {{expected '(' after 'property'}}
__declspec ( property ( ) ) int V1 ; // expected-error {{property does not specify a getter or a putter}}
__declspec ( property ( set ) ) int V2 ; // expected-error {{putter for property must be specified as 'put', not 'set'}} expected-error {{expected '=' after 'set'}}
__declspec ( property ( ptu ) ) int V3 ; // expected-error {{missing 'get=' or 'put='}}
__declspec ( property ( ptu = PutV ) ) int V4 ; // expected-error {{expected 'get' or 'put' in property declaration}}
__declspec ( property ( get ) ) int V5 ; // expected-error {{expected '=' after 'get'}}
__declspec ( property ( get & ) ) int V6 ; // expected-error {{expected '=' after 'get'}}
__declspec ( property ( get = ) ) int V7 ; // expected-error {{expected name of accessor method}}
__declspec ( property ( get = GetV ) ) int V8 ; // no-warning
__declspec ( property ( get = GetV = ) ) int V9 ; // expected-error {{expected ',' or ')' at end of property accessor list}}
__declspec ( property ( get = GetV , ) ) int V10 ; // expected-error {{expected 'get' or 'put' in property declaration}}
__declspec ( property ( get = GetV , put = SetV ) ) int V11 ; // no-warning
__declspec ( property ( get = GetV , put = SetV , get = GetV ) ) int V12 ; // expected-error {{property declaration specifies 'get' accessor twice}}
2014-12-13 19:34:16 +08:00
__declspec ( property ( get = GetV ) ) int V13 = 3 ; // expected-error {{property declaration cannot have an in-class initializer}}
2013-04-16 15:28:30 +08:00
int GetV ( ) { return 123 ; }
void SetV ( int v ) { }
} ;
void TestProperty ( ) {
StructWithProperty sp ;
sp . V8 ;
sp . V8 = 0 ; // expected-error {{no setter defined for property 'V8'}}
int i = sp . V11 ;
sp . V11 = i + + ;
sp . V11 + = 8 ;
sp . V11 + + ;
+ + sp . V11 ;
}
2014-06-01 00:32:22 +08:00
//expected-warning@+1 {{C++ operator 'and' (aka '&&') used as a macro name}}
# define and foo
2014-07-07 04:04:10 +08:00
2015-02-02 18:22:20 +08:00
struct __declspec ( uuid ( " 00000000-0000-0000-C000-000000000046 " ) ) __declspec ( novtable ) IUnknown { } ;
2014-07-07 04:04:10 +08:00
typedef bool ( __stdcall __stdcall * blarg ) ( int ) ;
void local_callconv ( ) {
bool ( __stdcall * p ) ( int ) ;
}
struct S7 {
int foo ( ) { return 12 ; }
__declspec ( property ( get = foo ) deprecated ) int t ; // expected-note {{'t' has been explicitly marked deprecated here}}
} ;
// Technically, this is legal (though it does nothing)
__declspec ( ) void quux ( void ) {
struct S7 s ;
int i = s . t ; // expected-warning {{'t' is deprecated}}
}
void * _alloca ( int ) ;
void foo ( void ) {
__declspec ( align ( 16 ) ) int * buffer = ( int * ) _alloca ( 9 ) ;
}
2014-08-14 08:49:23 +08:00
template < int * >
struct NullptrArg { } ;
NullptrArg < nullptr > a ;
2014-12-05 07:31:08 +08:00
// Ignored type qualifiers after comma in declarator lists
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}}
typedef void ( * ignored_quals_dummy2 ) ( ) , __fastcall ignored_quals2 ; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void ( * ignored_quals_dummy3 ) ( ) , __stdcall ignored_quals3 ; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void ( * ignored_quals_dummy4 ) ( ) , __thiscall ignored_quals4 ; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void ( * ignored_quals_dummy5 ) ( ) , __cdecl ignored_quals5 ; // expected-warning {{qualifiers after comma in declarator list are ignored}}
typedef void ( * ignored_quals_dummy6 ) ( ) , __vectorcall ignored_quals6 ; // expected-warning {{qualifiers after comma in declarator list are ignored}}
2015-02-26 08:57:33 +08:00
namespace {
bool f ( int ) ;
template < typename T >
struct A {
constexpr A ( T t ) {
__assume ( f ( t ) ) ; // expected-warning{{the argument to '__assume' has side effects that will be discarded}}
}
constexpr bool g ( ) { return false ; }
} ;
constexpr A < int > h ( ) {
A < int > b ( 0 ) ; // expected-note {{in instantiation of member function}}
return b ;
}
static_assert ( h ( ) . g ( ) = = false , " " ) ;
}
2015-04-19 15:53:29 +08:00
namespace {
__declspec ( align ( 16 ) ) struct align_before_key1 { } ;
__declspec ( align ( 16 ) ) struct align_before_key2 { } align_before_key2_var ;
__declspec ( align ( 16 ) ) struct align_before_key3 { } * align_before_key3_var ;
static_assert ( __alignof ( struct align_before_key1 ) = = 16 , " " ) ;
static_assert ( __alignof ( struct align_before_key2 ) = = 16 , " " ) ;
static_assert ( __alignof ( struct align_before_key3 ) = = 16 , " " ) ;
}
2015-07-08 13:55:00 +08:00
namespace PR24027 {
struct S {
template < typename T >
S ( T ) ;
} f ( [ ] { } ) ;
}