2009-12-16 04:14:24 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify %s
2015-11-12 03:34:47 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %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 ) ;
2015-11-12 03:34:47 +08:00
( void ) const_cast < A & & > ( A ( ) ) ;
# if __cplusplus <= 199711L // C++03 or earlier modes
// expected-warning@-2 {{rvalue references are a C++11 extension}}
# endif
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 } ;
2018-07-11 08:19:19 +08:00
extern const int * aub [ ] ;
// const_cast looks through arrays as of DR330.
( void ) const_cast < int * ( * ) [ 100 ] > ( & ar ) ; // ok
( void ) const_cast < int * ( * ) [ ] > ( & aub ) ; // ok
// ... but the array bound must exactly match.
( void ) const_cast < int * ( * ) [ ] > ( & ar ) ; // expected-error {{const_cast from 'const int *(*)[100]' to 'int *(*)[]' is not allowed}}
( void ) const_cast < int * ( * ) [ 99 ] > ( & ar ) ; // expected-error {{const_cast from 'const int *(*)[100]' to 'int *(*)[99]' is not allowed}}
( void ) const_cast < int * ( * ) [ 100 ] > ( & aub ) ; // expected-error {{const_cast from 'const int *(*)[]' 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}}
2015-11-12 03:34:47 +08:00
( void ) const_cast < int & & > ( 0 ) ; // expected-error {{const_cast from rvalue to reference type 'int &&'}}
# if __cplusplus <= 199711L // C++03 or earlier modes
// expected-warning@-2 {{rvalue references are a C++11 extension}}
# endif
2008-10-24 23:36:09 +08:00
return * * var3 ;
}
2014-12-16 08:46:30 +08:00
template < typename T >
char * PR21845 ( ) { return const_cast < char * > ( ( void ) T : : x ) ; } // expected-error {{const_cast from 'void' to 'char *' is not allowed}}