2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2009-01-25 05:16:55 +08:00
struct A { } ;
enum B { Dummy } ;
namespace C { }
2009-01-26 03:43:20 +08:00
struct D : A { } ;
2009-01-27 03:54:48 +08:00
struct E : A { } ;
struct F : D , E { } ;
struct G : virtual D { } ;
2009-01-25 05:16:55 +08:00
int A : : * pdi1 ;
int ( : : A : : * pdi2 ) ;
int ( A : : * pfi ) ( int ) ;
2010-02-26 16:45:28 +08:00
int B : : * pbi ; // expected-error {{expected a class or namespace}}
2009-01-25 05:16:55 +08:00
int C : : * pci ; // expected-error {{'pci' does not point into a class}}
void A : : * pdv ; // expected-error {{'pdv' declared as a member pointer to void}}
2009-06-30 08:06:57 +08:00
int & A : : * pdr ; // expected-error {{'pdr' declared as a member pointer to a reference}}
2009-01-25 07:29:36 +08:00
void f ( ) {
// This requires tentative parsing.
int ( A : : * pf ) ( int , int ) ;
2009-01-26 03:43:20 +08:00
// Implicit conversion to bool.
bool b = pdi1 ;
b = pfi ;
// Conversion from null pointer constant.
pf = 0 ;
pf = __null ;
// Conversion to member of derived.
int D : : * pdid = pdi1 ;
pdid = pdi2 ;
2009-01-27 03:54:48 +08:00
// Fail conversion due to ambiguity and virtuality.
2010-03-10 19:27:22 +08:00
int F : : * pdif = pdi1 ; // expected-error {{ambiguous conversion from pointer to member of base class 'A' to pointer to member of derived class 'F':}}
int G : : * pdig = pdi1 ; // expected-error {{conversion from pointer to member of class 'A' to pointer to member of class 'G' via virtual base 'D' is not allowed}}
2009-01-29 02:33:18 +08:00
// Conversion to member of base.
2010-04-09 08:35:39 +08:00
pdi1 = pdid ; // expected-error {{assigning to 'int A::*' from incompatible type 'int D::*'}}
2009-08-25 01:42:35 +08:00
// Comparisons
int ( A : : * pf2 ) ( int , int ) ;
int ( D : : * pf3 ) ( int , int ) = 0 ;
bool b1 = ( pf = = pf2 ) ; ( void ) b1 ;
bool b2 = ( pf ! = pf2 ) ; ( void ) b2 ;
bool b3 = ( pf = = pf3 ) ; ( void ) b3 ;
bool b4 = ( pf ! = 0 ) ; ( void ) b4 ;
2009-01-25 07:29:36 +08:00
}
2009-02-04 04:19:35 +08:00
2009-02-05 05:23:32 +08:00
struct TheBase
{
void d ( ) ;
} ;
struct HasMembers : TheBase
2009-02-04 04:19:35 +08:00
{
int i ;
void f ( ) ;
2009-02-05 05:23:32 +08:00
void g ( ) ;
void g ( int ) ;
static void g ( double ) ;
2009-02-04 04:19:35 +08:00
} ;
namespace Fake
{
int i ;
void f ( ) ;
}
void g ( ) {
2009-02-05 05:23:32 +08:00
HasMembers hm ;
2009-02-04 04:19:35 +08:00
int HasMembers : : * pmi = & HasMembers : : i ;
int * pni = & Fake : : i ;
2009-02-05 05:23:32 +08:00
int * pmii = & hm . i ;
2009-02-04 04:19:35 +08:00
2009-02-05 05:23:32 +08:00
void ( HasMembers : : * pmf ) ( ) = & HasMembers : : f ;
2009-02-04 04:19:35 +08:00
void ( * pnf ) ( ) = & Fake : : f ;
2010-08-27 17:08:28 +08:00
& hm . f ; // expected-error {{cannot create a non-constant pointer to member function}}
2009-02-05 05:23:32 +08:00
void ( HasMembers : : * pmgv ) ( ) = & HasMembers : : g ;
void ( HasMembers : : * pmgi ) ( int ) = & HasMembers : : g ;
void ( * pmgd ) ( double ) = & HasMembers : : g ;
void ( HasMembers : : * pmd ) ( ) = & HasMembers : : d ;
2009-02-04 04:19:35 +08:00
}
2009-02-07 08:15:38 +08:00
2010-04-10 18:14:54 +08:00
struct Incomplete ; // expected-note {{forward declaration}}
2009-02-07 08:41:42 +08:00
2009-02-07 08:15:38 +08:00
void h ( ) {
HasMembers hm , * phm = & hm ;
int HasMembers : : * pi = & HasMembers : : i ;
hm . * pi = 0 ;
int i = phm - > * pi ;
( void ) & ( hm . * pi ) ;
( void ) & ( phm - > * pi ) ;
2009-10-09 02:00:39 +08:00
( void ) & ( ( & hm ) - > * pi ) ;
2009-02-07 08:15:38 +08:00
void ( HasMembers : : * pf ) ( ) = & HasMembers : : f ;
( hm . * pf ) ( ) ;
( phm - > * pf ) ( ) ;
2009-02-07 08:41:42 +08:00
2010-03-10 19:27:22 +08:00
( void ) ( hm - > * pi ) ; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'HasMembers'}}
( void ) ( phm . * pi ) ; // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'HasMembers *'}}
2009-02-07 08:41:42 +08:00
( void ) ( i . * pi ) ; // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
int * ptr ;
( void ) ( ptr - > * pi ) ; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
int A : : * pai = 0 ;
D d , * pd = & d ;
( void ) ( d . * pai ) ;
( void ) ( pd - > * pai ) ;
F f , * ptrf = & f ;
2010-03-10 19:27:22 +08:00
( void ) ( f . * pai ) ; // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'F'}}
( void ) ( ptrf - > * pai ) ; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'F *'}}
2009-02-07 08:41:42 +08:00
2009-03-25 03:52:54 +08:00
( void ) ( hm . * i ) ; // expected-error {{pointer-to-member}}
( void ) ( phm - > * i ) ; // expected-error {{pointer-to-member}}
2009-02-07 08:41:42 +08:00
Incomplete * inc ;
int Incomplete : : * pii = 0 ;
2010-04-10 18:14:54 +08:00
( void ) ( inc - > * pii ) ; // expected-error {{pointer into incomplete}}
2009-02-07 08:15:38 +08:00
}
struct OverloadsPtrMem
{
int operator - > * ( const char * ) ;
} ;
void i ( ) {
OverloadsPtrMem m ;
int foo = m - > * " Awesome! " ;
}
2010-01-11 23:56:56 +08:00
namespace pr5985 {
struct c {
void h ( ) ;
void f ( ) {
void ( c : : * p ) ( ) ;
p = & h ; // expected-error {{must explicitly qualify}}
2010-08-27 17:08:28 +08:00
p = & this - > h ; // expected-error {{cannot create a non-constant pointer to member function}}
p = & ( * this ) . h ; // expected-error {{cannot create a non-constant pointer to member function}}
2010-01-11 23:56:56 +08:00
}
} ;
}
2010-04-24 01:18:26 +08:00
namespace pr6783 {
struct Base { } ;
struct X ; // expected-note {{forward declaration}}
int test1 ( int Base : : * p2m , X * object )
{
return object - > * p2m ; // expected-error {{left hand operand to ->*}}
}
}
2010-05-22 04:29:55 +08:00
namespace PR7176 {
namespace base
{
struct Process
{ } ;
struct Continuous : Process
{
bool cond ( ) ;
} ;
}
typedef bool ( base : : Process : : * Condition ) ( ) ;
void m ( )
{ ( void ) ( Condition ) & base : : Continuous : : cond ; }
}
2010-08-27 17:08:28 +08:00
namespace rdar8358512 {
// We can't call this with an overload set because we're not allowed
// to look into overload sets unless the parameter has some kind of
// function type.
2010-08-28 03:56:05 +08:00
template < class F > void bind ( F f ) ; // expected-note 12 {{candidate template ignored}}
2010-08-27 17:08:28 +08:00
template < class F , class T > void bindmem ( F ( T : : * f ) ( ) ) ; // expected-note 4 {{candidate template ignored}}
template < class F > void bindfn ( F ( * f ) ( ) ) ; // expected-note 4 {{candidate template ignored}}
struct A {
void nonstat ( ) ;
void nonstat ( int ) ;
void mixed ( ) ;
static void mixed ( int ) ;
static void stat ( ) ;
static void stat ( int ) ;
template < typename T > struct Test0 {
void test ( ) {
bind ( & nonstat ) ; // expected-error {{no matching function for call}}
bind ( & A : : nonstat ) ; // expected-error {{no matching function for call}}
bind ( & mixed ) ; // expected-error {{no matching function for call}}
bind ( & A : : mixed ) ; // expected-error {{no matching function for call}}
bind ( & stat ) ; // expected-error {{no matching function for call}}
bind ( & A : : stat ) ; // expected-error {{no matching function for call}}
}
} ;
template < typename T > struct Test1 {
void test ( ) {
bindmem ( & nonstat ) ; // expected-error {{no matching function for call}}
bindmem ( & A : : nonstat ) ;
bindmem ( & mixed ) ; // expected-error {{no matching function for call}}
bindmem ( & A : : mixed ) ;
bindmem ( & stat ) ; // expected-error {{no matching function for call}}
bindmem ( & A : : stat ) ; // expected-error {{no matching function for call}}
}
} ;
template < typename T > struct Test2 {
void test ( ) {
bindfn ( & nonstat ) ; // expected-error {{no matching function for call}}
bindfn ( & A : : nonstat ) ; // expected-error {{no matching function for call}}
bindfn ( & mixed ) ; // expected-error {{no matching function for call}}
bindfn ( & A : : mixed ) ; // expected-error {{no matching function for call}}
bindfn ( & stat ) ;
bindfn ( & A : : stat ) ;
}
} ;
} ;
2010-08-28 03:56:05 +08:00
template < class T > class B {
void nonstat ( ) ;
void nonstat ( int ) ;
void mixed ( ) ;
static void mixed ( int ) ;
static void stat ( ) ;
static void stat ( int ) ;
// None of these can be diagnosed yet, because the arguments are
// still dependent.
void test0a ( ) {
bind ( & nonstat ) ;
bind ( & B : : nonstat ) ;
bind ( & mixed ) ;
bind ( & B : : mixed ) ;
bind ( & stat ) ;
bind ( & B : : stat ) ;
}
void test0b ( ) {
bind ( & nonstat ) ; // expected-error {{no matching function for call}}
bind ( & B : : nonstat ) ; // expected-error {{no matching function for call}}
bind ( & mixed ) ; // expected-error {{no matching function for call}}
bind ( & B : : mixed ) ; // expected-error {{no matching function for call}}
bind ( & stat ) ; // expected-error {{no matching function for call}}
bind ( & B : : stat ) ; // expected-error {{no matching function for call}}
}
} ;
template void B < int > : : test0b ( ) ; // expected-note {{in instantiation}}
2010-08-27 17:08:28 +08:00
}