2009-03-24 05:24:46 +03:00
// RUN: clang-cc -fsyntax-only -verify %s
2008-10-24 19:36:09 +04:00
2009-01-27 01:19:12 +03:00
struct A { } ;
2008-10-24 19:36:09 +04:00
// See if aliasing can confuse this baby.
typedef char c ;
typedef c * cp ;
typedef cp * cpp ;
typedef cpp * cppp ;
typedef cppp & cpppr ;
typedef const cppp & cpppcr ;
typedef const char cc ;
typedef cc * ccp ;
typedef volatile ccp ccvp ;
typedef ccvp * ccvpp ;
typedef const volatile ccvpp ccvpcvp ;
typedef ccvpcvp * ccvpcvpp ;
typedef int iar [ 100 ] ;
typedef iar & iarr ;
typedef int ( * f ) ( int ) ;
char * * * good_const_cast_test ( ccvpcvpp var )
{
// Cast away deep consts and volatiles.
char * * * var2 = const_cast < cppp > ( var ) ;
2008-10-29 22:45:21 +03:00
char * * * const & var3 = var2 ;
2008-10-24 19:36:09 +04:00
// Const reference to reference.
char * * * & var4 = const_cast < cpppr > ( var3 ) ;
// Drop reference. Intentionally without qualifier change.
char * * * var5 = const_cast < cppp > ( var4 ) ;
const int ar [ 100 ] = { 0 } ;
2009-02-20 02:45:49 +03:00
int ( & rar ) [ 100 ] = const_cast < iarr > ( ar ) ; // expected-error {{const_cast from 'int const [100]' to 'iarr' (aka 'iar &') is not allowed}}
2008-10-24 19:36:09 +04:00
// Array decay. Intentionally without qualifier change.
int * pi = const_cast < int * > ( ar ) ;
f fp = 0 ;
// Don't misidentify fn** as a function pointer.
f * fpp = const_cast < f * > ( & fp ) ;
2009-01-27 01:19:12 +03:00
int const A : : * const A : : * icapcap = 0 ;
int A : : * A : : * iapap = const_cast < int A : : * A : : * > ( icapcap ) ;
2008-10-24 19:36:09 +04:00
return var4 ;
}
short * bad_const_cast_test ( char const * volatile * const volatile * var )
{
// Different pointer levels.
char * * var2 = const_cast < char * * > ( var ) ; // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'char **' is not allowed}}
// Different final type.
short * * * var3 = const_cast < short * * * > ( var ) ; // expected-error {{const_cast from 'char const *volatile *const volatile *' to 'short ***' is not allowed}}
// Rvalue to reference.
char * * * & var4 = const_cast < cpppr > ( & var2 ) ; // expected-error {{const_cast from rvalue to reference type 'cpppr'}}
// Non-pointer.
char v = const_cast < char > ( * * var2 ) ; // expected-error {{const_cast to 'char', which is not a reference, pointer-to-object, or pointer-to-data-member}}
const int * ar [ 100 ] = { 0 } ;
// Not even lenient g++ accepts this.
int * ( * rar ) [ 100 ] = const_cast < int * ( * ) [ 100 ] > ( & ar ) ; // expected-error {{const_cast from 'int const *(*)[100]' to 'int *(*)[100]' is not allowed}}
f fp1 = 0 ;
// Function pointers.
2009-02-20 02:45:49 +03:00
f fp2 = const_cast < f > ( fp1 ) ; // expected-error {{const_cast to 'f' (aka 'int (*)(int)'), which is not a reference, pointer-to-object, or pointer-to-data-member}}
2009-01-27 01:19:12 +03:00
void ( A : : * mfn ) ( ) = 0 ;
2009-06-03 06:06:50 +04:00
( void ) const_cast < void ( A : : * ) ( ) > ( mfn ) ; // expected-error {{const_cast to 'void (struct A::*)()', which is not a reference, pointer-to-object, or pointer-to-data-member}}
2008-10-24 19:36:09 +04:00
return * * var3 ;
}