2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2008-10-24 23:36:09 +08:00
2009-01-27 06:19:12 +08:00
struct A { } ;
2008-10-24 23:36:09 +08: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-30 03:45:21 +08:00
char * * * const & var3 = var2 ;
2008-10-24 23:36:09 +08:00
// Const reference to reference.
char * * * & var4 = const_cast < cpppr > ( var3 ) ;
// Drop reference. Intentionally without qualifier change.
char * * * var5 = const_cast < cppp > ( var4 ) ;
2009-12-29 16:05:19 +08:00
// Const array to array reference.
2008-10-24 23:36:09 +08:00
const int ar [ 100 ] = { 0 } ;
2009-12-29 16:05:19 +08:00
int ( & rar ) [ 100 ] = const_cast < iarr > ( ar ) ;
2008-10-24 23:36:09 +08: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 06:19:12 +08:00
int const A : : * const A : : * icapcap = 0 ;
int A : : * A : : * iapap = const_cast < int A : : * A : : * > ( icapcap ) ;
2013-06-15 06:27:52 +08:00
( void ) const_cast < A & & > ( A ( ) ) ; // expected-warning {{C++11}}
2009-01-27 06:19:12 +08:00
2008-10-24 23:36:09 +08:00
return var4 ;
}
short * bad_const_cast_test ( char const * volatile * const volatile * var )
{
// Different pointer levels.
2010-09-05 08:04:01 +08:00
char * * var2 = const_cast < char * * > ( var ) ; // expected-error {{const_cast from 'const char *volatile *const volatile *' to 'char **' is not allowed}}
2008-10-24 23:36:09 +08:00
// Different final type.
2010-09-05 08:04:01 +08:00
short * * * var3 = const_cast < short * * * > ( var ) ; // expected-error {{const_cast from 'const char *volatile *const volatile *' to 'short ***' is not allowed}}
2008-10-24 23:36:09 +08:00
// 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.
2010-09-05 08:04:01 +08:00
int * ( * rar ) [ 100 ] = const_cast < int * ( * ) [ 100 ] > ( & ar ) ; // expected-error {{const_cast from 'const int *(*)[100]' to 'int *(*)[100]' is not allowed}}
2008-10-24 23:36:09 +08:00
f fp1 = 0 ;
// Function pointers.
2009-02-20 07:45:49 +08: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 06:19:12 +08:00
void ( A : : * mfn ) ( ) = 0 ;
2013-12-14 09:07:05 +08:00
( void ) const_cast < void ( A : : * ) ( ) > ( mfn ) ; // expected-error-re {{const_cast to 'void (A::*)(){{( __attribute__\(\(thiscall\)\))?}}', which is not a reference, pointer-to-object, or pointer-to-data-member}}
2013-06-15 06:27:52 +08:00
( void ) const_cast < int & & > ( 0 ) ; // expected-error {{const_cast from rvalue to reference type 'int &&'}} expected-warning {{C++11}}
2008-10-24 23:36:09 +08:00
return * * var3 ;
}