2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -faccess-control %s
2008-10-31 22:43:28 +08:00
struct A { } ;
struct B : public A { } ; // Single public base.
struct C1 : public virtual B { } ; // Single virtual base.
struct C2 : public virtual B { } ;
struct D : public C1 , public C2 { } ; // Diamond
2010-02-10 17:31:12 +08:00
struct E : private A { } ; // Single private base. expected-note 3 {{declared private here}}
2008-10-31 22:43:28 +08:00
struct F : public C1 { } ; // Single path to B with virtual.
struct G1 : public B { } ;
struct G2 : public B { } ;
struct H : public G1 , public G2 { } ; // Ambiguous path to B.
enum Enum { En1 , En2 } ;
enum Onom { On1 , On2 } ;
2009-07-25 23:41:38 +08:00
struct Co1 { operator int ( ) ; } ;
struct Co2 { Co2 ( int ) ; } ;
struct Co3 { } ;
struct Co4 { Co4 ( Co3 ) ; operator Co3 ( ) ; } ;
2008-10-31 22:43:28 +08:00
// Explicit implicits
void t_529_2 ( )
{
int i = 1 ;
( void ) static_cast < float > ( i ) ;
double d = 1.0 ;
( void ) static_cast < float > ( d ) ;
( void ) static_cast < int > ( d ) ;
( void ) static_cast < char > ( i ) ;
( void ) static_cast < unsigned long > ( i ) ;
( void ) static_cast < int > ( En1 ) ;
( void ) static_cast < double > ( En1 ) ;
( void ) static_cast < int & > ( i ) ;
( void ) static_cast < const int & > ( i ) ;
int ar [ 1 ] ;
( void ) static_cast < const int * > ( ar ) ;
( void ) static_cast < void ( * ) ( ) > ( t_529_2 ) ;
( void ) static_cast < void * > ( 0 ) ;
( void ) static_cast < void * > ( ( int * ) 0 ) ;
( void ) static_cast < volatile const void * > ( ( const int * ) 0 ) ;
( void ) static_cast < A * > ( ( B * ) 0 ) ;
( void ) static_cast < A & > ( * ( ( B * ) 0 ) ) ;
( void ) static_cast < const B * > ( ( C1 * ) 0 ) ;
( void ) static_cast < B & > ( * ( ( C1 * ) 0 ) ) ;
( void ) static_cast < A * > ( ( D * ) 0 ) ;
( void ) static_cast < const A & > ( * ( ( D * ) 0 ) ) ;
2009-01-29 02:33:18 +08:00
( void ) static_cast < int B : : * > ( ( int A : : * ) 0 ) ;
( void ) static_cast < void ( B : : * ) ( ) > ( ( void ( A : : * ) ( ) ) 0 ) ;
2008-10-31 22:43:28 +08:00
2009-07-25 23:41:38 +08:00
( void ) static_cast < int > ( Co1 ( ) ) ;
( void ) static_cast < Co2 > ( 1 ) ;
( void ) static_cast < Co3 > ( static_cast < Co4 > ( Co3 ( ) ) ) ;
2008-10-31 22:43:28 +08:00
// Bad code below
( void ) static_cast < void * > ( ( const int * ) 0 ) ; // expected-error {{static_cast from 'int const *' to 'void *' is not allowed}}
2010-03-10 19:27:22 +08:00
( void ) static_cast < A * > ( ( E * ) 0 ) ; // expected-error {{cannot cast 'E' to its private base class 'A'}}
2009-11-15 05:15:49 +08:00
( void ) static_cast < A * > ( ( H * ) 0 ) ; // expected-error {{ambiguous conversion}}
2008-10-31 22:43:28 +08:00
( void ) static_cast < int > ( ( int * ) 0 ) ; // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
2010-03-10 19:27:22 +08:00
( void ) static_cast < A * * > ( ( B * * ) 0 ) ; // expected-error {{static_cast from 'B **' to 'A **' is not allowed}}
2010-03-25 07:38:29 +08:00
( void ) static_cast < char & > ( i ) ; // expected-error {{non-const lvalue reference to type 'char' cannot bind to a value of unrelated type 'int'}}
2008-10-31 22:43:28 +08:00
}
// Anything to void
void t_529_4 ( )
{
static_cast < void > ( 1 ) ;
static_cast < void > ( t_529_4 ) ;
}
// Static downcasts
void t_529_5_8 ( )
{
( void ) static_cast < B * > ( ( A * ) 0 ) ;
( void ) static_cast < B & > ( * ( ( A * ) 0 ) ) ;
( void ) static_cast < const G1 * > ( ( A * ) 0 ) ;
( void ) static_cast < const G1 & > ( * ( ( A * ) 0 ) ) ;
// Bad code below
2010-03-10 19:27:22 +08:00
( void ) static_cast < C1 * > ( ( A * ) 0 ) ; // expected-error {{cannot cast 'A *' to 'C1 *' via virtual base 'B'}}
( void ) static_cast < C1 & > ( * ( ( A * ) 0 ) ) ; // expected-error {{cannot cast 'A' to 'C1 &' via virtual base 'B'}}
( void ) static_cast < D * > ( ( A * ) 0 ) ; // expected-error {{cannot cast 'A *' to 'D *' via virtual base 'B'}}
( void ) static_cast < D & > ( * ( ( A * ) 0 ) ) ; // expected-error {{cannot cast 'A' to 'D &' via virtual base 'B'}}
( void ) static_cast < B * > ( ( const A * ) 0 ) ; // expected-error {{static_cast from 'A const *' to 'B *' casts away constness}}
( void ) static_cast < B & > ( * ( ( const A * ) 0 ) ) ; // expected-error {{static_cast from 'A const' to 'B &' casts away constness}}
( void ) static_cast < E * > ( ( A * ) 0 ) ; // expected-error {{cannot cast private base class 'A' to 'E'}}
( void ) static_cast < E & > ( * ( ( A * ) 0 ) ) ; // expected-error {{cannot cast private base class 'A' to 'E'}}
( void ) static_cast < H * > ( ( A * ) 0 ) ; // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
( void ) static_cast < H & > ( * ( ( A * ) 0 ) ) ; // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
( void ) static_cast < E * > ( ( B * ) 0 ) ; // expected-error {{static_cast from 'B *' to 'E *' is not allowed}}
2010-03-25 07:38:29 +08:00
( void ) static_cast < E & > ( * ( ( B * ) 0 ) ) ; // expected-error {{non-const lvalue reference to type 'E' cannot bind to a value of unrelated type 'B'}}
2008-10-31 22:43:28 +08:00
// TODO: Test inaccessible base in context where it's accessible, i.e.
// member function and friend.
// TODO: Test DR427. This requires user-defined conversions, though.
}
// Enum conversions
void t_529_7 ( )
{
( void ) static_cast < Enum > ( 1 ) ;
( void ) static_cast < Enum > ( 1.0 ) ;
( void ) static_cast < Onom > ( En1 ) ;
// Bad code below
2010-03-10 19:27:22 +08:00
( void ) static_cast < Enum > ( ( int * ) 0 ) ; // expected-error {{static_cast from 'int *' to 'Enum' is not allowed}}
2008-10-31 22:43:28 +08:00
}
// Void pointer to object pointer
void t_529_10 ( )
{
( void ) static_cast < int * > ( ( void * ) 0 ) ;
( void ) static_cast < const A * > ( ( void * ) 0 ) ;
// Bad code below
2008-11-06 01:54:26 +08:00
( void ) static_cast < int * > ( ( const void * ) 0 ) ; // expected-error {{static_cast from 'void const *' to 'int *' casts away constness}}
2009-06-03 10:06:50 +08:00
( void ) static_cast < void ( * ) ( ) > ( ( void * ) 0 ) ; // expected-error {{static_cast from 'void *' to 'void (*)()' is not allowed}}
2008-10-31 22:43:28 +08:00
}
2009-01-29 02:33:18 +08:00
// Member pointer upcast.
void t_529_9 ( )
{
( void ) static_cast < int A : : * > ( ( int B : : * ) 0 ) ;
// Bad code below
2010-03-10 19:27:22 +08:00
( void ) static_cast < int A : : * > ( ( int H : : * ) 0 ) ; // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
( void ) static_cast < int A : : * > ( ( int F : : * ) 0 ) ; // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
2009-01-29 02:33:18 +08:00
}
2009-10-22 23:07:22 +08:00
// PR 5261 - static_cast should instantiate template if possible
namespace pr5261 {
struct base { } ;
template < typename E > struct derived : public base { } ;
template < typename E > struct outer {
base * pb ;
~ outer ( ) { ( void ) static_cast < derived < E > * > ( pb ) ; }
} ;
outer < int > EntryList ;
}
2009-11-14 11:27:21 +08:00
// Initialization by constructor
struct X0 ;
struct X1 {
X1 ( ) ;
X1 ( X1 & ) ;
X1 ( const X0 & ) ;
operator X0 ( ) const ;
} ;
struct X0 { } ;
void test_ctor_init ( ) {
( void ) static_cast < X1 > ( X1 ( ) ) ;
}
2009-11-15 17:20:52 +08:00
// Casting away constness
struct X2 {
} ;
struct X3 : X2 {
} ;
struct X4 {
typedef const X3 X3_typedef ;
void f ( ) const {
( void ) static_cast < X3_typedef * > ( x2 ) ;
}
const X2 * x2 ;
} ;
2010-01-31 19:51:51 +08:00
// PR5897 - accept static_cast from const void* to const int (*)[1].
2010-01-31 19:52:52 +08:00
void PR5897 ( ) { ( void ) static_cast < const int ( * ) [ 1 ] > ( ( const void * ) 0 ) ; }
2010-03-08 07:24:59 +08:00
namespace PR6072 {
struct A { } ;
struct B : A { void f ( int ) ; void f ( ) ; } ;
struct C : B { } ;
struct D { } ;
void f ( ) {
( void ) static_cast < void ( A : : * ) ( ) > ( & B : : f ) ;
( void ) static_cast < void ( B : : * ) ( ) > ( & B : : f ) ;
( void ) static_cast < void ( C : : * ) ( ) > ( & B : : f ) ;
2010-03-10 19:27:22 +08:00
( void ) static_cast < void ( D : : * ) ( ) > ( & B : : f ) ; // expected-error{{static_cast from '<overloaded function type>' to 'void (PR6072::D::*)()' is not allowed}}
2010-03-08 07:24:59 +08:00
}
}