2010-01-01 10:34:51 +00:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2009-06-02 17:58:47 +00:00
struct A { } ;
enum B { Dummy } ;
namespace C { }
struct D : A { } ;
struct E : A { } ;
struct F : D , E { } ;
struct G : virtual D { } ;
int A : : * pdi1 ;
int ( : : A : : * pdi2 ) ;
int ( A : : * pfi ) ( int ) ;
2010-03-03 17:28:16 +00:00
int B : : * pbi ; // expected-error {{expected a class or namespace}}
2009-06-02 17:58:47 +00: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-07-04 13:58:54 +00:00
int & A : : * pdr ; // expected-error {{'pdr' declared as a member pointer to a reference}}
2009-06-02 17:58:47 +00:00
void f ( ) {
// This requires tentative parsing.
int ( A : : * pf ) ( int , int ) ;
// 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 ;
// Fail conversion due to ambiguity and virtuality.
2010-03-10 17:45:58 +00: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-06-02 17:58:47 +00:00
// Conversion to member of base.
2010-03-10 17:45:58 +00:00
pdi1 = pdid ; // expected-error {{incompatible type assigning 'int D::*', expected 'int A::*'}}
2009-10-14 18:03:49 +00: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-06-02 17:58:47 +00:00
}
struct TheBase
{
void d ( ) ;
} ;
struct HasMembers : TheBase
{
int i ;
void f ( ) ;
void g ( ) ;
void g ( int ) ;
static void g ( double ) ;
} ;
namespace Fake
{
int i ;
void f ( ) ;
}
void g ( ) {
HasMembers hm ;
int HasMembers : : * pmi = & HasMembers : : i ;
int * pni = & Fake : : i ;
int * pmii = & hm . i ;
void ( HasMembers : : * pmf ) ( ) = & HasMembers : : f ;
void ( * pnf ) ( ) = & Fake : : f ;
2010-01-15 15:39:40 +00:00
& hm . f ; // expected-error {{must explicitly qualify}} expected-warning{{result unused}}
2009-06-02 17:58:47 +00:00
void ( HasMembers : : * pmgv ) ( ) = & HasMembers : : g ;
void ( HasMembers : : * pmgi ) ( int ) = & HasMembers : : g ;
void ( * pmgd ) ( double ) = & HasMembers : : g ;
void ( HasMembers : : * pmd ) ( ) = & HasMembers : : d ;
}
struct Incomplete ;
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-14 18:03:49 +00:00
( void ) & ( ( & hm ) - > * pi ) ;
2009-06-02 17:58:47 +00:00
void ( HasMembers : : * pf ) ( ) = & HasMembers : : f ;
( hm . * pf ) ( ) ;
( phm - > * pf ) ( ) ;
2010-03-10 17:45:58 +00: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-06-02 17:58:47 +00: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 17:45:58 +00: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-06-02 17:58:47 +00:00
( void ) ( hm . * i ) ; // expected-error {{pointer-to-member}}
( void ) ( phm - > * i ) ; // expected-error {{pointer-to-member}}
Incomplete * inc ;
int Incomplete : : * pii = 0 ;
( void ) ( inc - > * pii ) ; // okay
}
struct OverloadsPtrMem
{
int operator - > * ( const char * ) ;
} ;
void i ( ) {
OverloadsPtrMem m ;
int foo = m - > * " Awesome! " ;
}
2010-01-15 15:39:40 +00:00
namespace pr5985 {
struct c {
void h ( ) ;
void f ( ) {
void ( c : : * p ) ( ) ;
p = & h ; // expected-error {{must explicitly qualify}}
p = & this - > h ; // expected-error {{must explicitly qualify}}
p = & ( * this ) . h ; // expected-error {{must explicitly qualify}}
}
} ;
}