2010-09-08 06:54:28 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding %s
2008-10-24 23:36:09 +08:00
2009-11-22 15:05:50 +08:00
# include <stdint.h>
2008-10-24 23:36:09 +08:00
enum test { testval = 1 } ;
struct structure { int m ; } ;
typedef void ( * fnptr ) ( ) ;
// Test the conversion to self.
void self_conversion ( )
{
// T*->T* is allowed, T->T in general not.
int i = 0 ;
( void ) reinterpret_cast < int > ( i ) ; // expected-error {{reinterpret_cast from 'int' to 'int' is not allowed}}
structure s ;
2010-03-10 19:27:22 +08:00
( void ) reinterpret_cast < structure > ( s ) ; // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
2008-10-24 23:36:09 +08:00
int * pi = 0 ;
( void ) reinterpret_cast < int * > ( pi ) ;
}
// Test conversion between pointer and integral types, as in /3 and /4.
void integral_conversion ( )
{
void * vp = reinterpret_cast < void * > ( testval ) ;
2009-11-22 15:05:50 +08:00
intptr_t i = reinterpret_cast < intptr_t > ( vp ) ;
( void ) reinterpret_cast < float * > ( i ) ;
fnptr fnp = reinterpret_cast < fnptr > ( i ) ;
2008-10-24 23:36:09 +08:00
( void ) reinterpret_cast < char > ( fnp ) ; // expected-error {{cast from pointer to smaller type 'char' loses information}}
2009-11-22 15:05:50 +08:00
( void ) reinterpret_cast < intptr_t > ( fnp ) ;
2008-10-24 23:36:09 +08:00
}
void pointer_conversion ( )
{
int * p1 = 0 ;
float * p2 = reinterpret_cast < float * > ( p1 ) ;
structure * p3 = reinterpret_cast < structure * > ( p2 ) ;
typedef int * * ppint ;
ppint * deep = reinterpret_cast < ppint * > ( p3 ) ;
( void ) reinterpret_cast < fnptr * > ( deep ) ;
}
void constness ( )
{
int * * * const ipppc = 0 ;
// Valid: T1* -> T2 const*
int const * icp = reinterpret_cast < int const * > ( ipppc ) ;
// Invalid: T1 const* -> T2*
Implement appropriate semantics for C++ casting and conversion when
dealing with address-space- and GC-qualified pointers. Previously,
these qualifiers were being treated just like cvr-qualifiers (in some
cases) or were completely ignored, leading to uneven behavior. For
example, const_cast would allow conversion between pointers to
different address spaces.
The new semantics are fairly simple: reinterpret_cast can be used to
explicitly cast between pointers to different address spaces
(including adding/removing addresss spaces), while
static_cast/dynamic_cast/const_cast do not tolerate any changes in the
address space. C-style casts can add/remove/change address spaces
through the reinterpret_cast mechanism. Other non-CVR qualifiers
(e.g., Objective-C GC qualifiers) work similarly.
As part of this change, I tweaked the "casts away constness"
diagnostic to use the term "casts away qualifiers". The term
"constness" actually comes from the C++ standard, despite the fact
that removing "volatile" also falls under that category. In Clang, we
also have restrict, address spaces, ObjC GC attributes, etc., so the
more general "qualifiers" is clearer.
llvm-svn: 129583
2011-04-16 01:59:54 +08:00
( void ) reinterpret_cast < int * > ( icp ) ; // expected-error {{reinterpret_cast from 'const int *' to 'int *' casts away qualifiers}}
2008-10-24 23:36:09 +08:00
// Invalid: T1*** -> T2 const* const**
Implement appropriate semantics for C++ casting and conversion when
dealing with address-space- and GC-qualified pointers. Previously,
these qualifiers were being treated just like cvr-qualifiers (in some
cases) or were completely ignored, leading to uneven behavior. For
example, const_cast would allow conversion between pointers to
different address spaces.
The new semantics are fairly simple: reinterpret_cast can be used to
explicitly cast between pointers to different address spaces
(including adding/removing addresss spaces), while
static_cast/dynamic_cast/const_cast do not tolerate any changes in the
address space. C-style casts can add/remove/change address spaces
through the reinterpret_cast mechanism. Other non-CVR qualifiers
(e.g., Objective-C GC qualifiers) work similarly.
As part of this change, I tweaked the "casts away constness"
diagnostic to use the term "casts away qualifiers". The term
"constness" actually comes from the C++ standard, despite the fact
that removing "volatile" also falls under that category. In Clang, we
also have restrict, address spaces, ObjC GC attributes, etc., so the
more general "qualifiers" is clearer.
llvm-svn: 129583
2011-04-16 01:59:54 +08:00
int const * const * * icpcpp = reinterpret_cast < int const * const * * > ( ipppc ) ; // expected-error {{reinterpret_cast from 'int ***' to 'const int *const **' casts away qualifiers}}
2008-10-24 23:36:09 +08:00
// Valid: T1* -> T2*
int * ip = reinterpret_cast < int * > ( icpcpp ) ;
// Valid: T* -> T const*
( void ) reinterpret_cast < int const * > ( ip ) ;
// Valid: T*** -> T2 const* const* const*
( void ) reinterpret_cast < int const * const * const * > ( ipppc ) ;
}
void fnptrs ( )
{
typedef int ( * fnptr2 ) ( int ) ;
fnptr fp = 0 ;
( void ) reinterpret_cast < fnptr2 > ( fp ) ;
void * vp = reinterpret_cast < void * > ( fp ) ;
( void ) reinterpret_cast < fnptr > ( vp ) ;
}
void refs ( )
{
long l = 0 ;
char & c = reinterpret_cast < char & > ( l ) ;
// Bad: from rvalue
( void ) reinterpret_cast < int & > ( & c ) ; // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
}
2009-01-28 07:18:31 +08:00
void memptrs ( )
{
const int structure : : * psi = 0 ;
( void ) reinterpret_cast < const float structure : : * > ( psi ) ;
Implement appropriate semantics for C++ casting and conversion when
dealing with address-space- and GC-qualified pointers. Previously,
these qualifiers were being treated just like cvr-qualifiers (in some
cases) or were completely ignored, leading to uneven behavior. For
example, const_cast would allow conversion between pointers to
different address spaces.
The new semantics are fairly simple: reinterpret_cast can be used to
explicitly cast between pointers to different address spaces
(including adding/removing addresss spaces), while
static_cast/dynamic_cast/const_cast do not tolerate any changes in the
address space. C-style casts can add/remove/change address spaces
through the reinterpret_cast mechanism. Other non-CVR qualifiers
(e.g., Objective-C GC qualifiers) work similarly.
As part of this change, I tweaked the "casts away constness"
diagnostic to use the term "casts away qualifiers". The term
"constness" actually comes from the C++ standard, despite the fact
that removing "volatile" also falls under that category. In Clang, we
also have restrict, address spaces, ObjC GC attributes, etc., so the
more general "qualifiers" is clearer.
llvm-svn: 129583
2011-04-16 01:59:54 +08:00
( void ) reinterpret_cast < int structure : : * > ( psi ) ; // expected-error {{reinterpret_cast from 'const int structure::*' to 'int structure::*' casts away qualifiers}}
2009-01-28 07:18:31 +08:00
void ( structure : : * psf ) ( ) = 0 ;
( void ) reinterpret_cast < int ( structure : : * ) ( ) > ( psf ) ;
2010-09-05 08:04:01 +08:00
( void ) reinterpret_cast < void ( structure : : * ) ( ) > ( psi ) ; // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
2010-03-10 19:27:22 +08:00
( void ) reinterpret_cast < int structure : : * > ( psf ) ; // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
2009-01-28 07:18:31 +08:00
// Cannot cast from integers to member pointers, not even the null pointer
// literal.
2010-03-10 19:27:22 +08:00
( void ) reinterpret_cast < void ( structure : : * ) ( ) > ( 0 ) ; // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
( void ) reinterpret_cast < int structure : : * > ( 0 ) ; // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
2009-01-28 07:18:31 +08:00
}
2009-11-19 02:10:53 +08:00
2010-06-05 06:47:55 +08:00
namespace PR5545 {
2009-11-19 02:10:53 +08:00
// PR5545
class A ;
class B ;
void ( A : : * a ) ( ) ;
void ( B : : * b ) ( ) = reinterpret_cast < void ( B : : * ) ( ) > ( a ) ;
2010-06-05 06:47:55 +08:00
}
// <rdar://problem/8018292>
void const_arrays ( ) {
typedef char STRING [ 10 ] ;
const STRING * s ;
const char * c ;
Implement appropriate semantics for C++ casting and conversion when
dealing with address-space- and GC-qualified pointers. Previously,
these qualifiers were being treated just like cvr-qualifiers (in some
cases) or were completely ignored, leading to uneven behavior. For
example, const_cast would allow conversion between pointers to
different address spaces.
The new semantics are fairly simple: reinterpret_cast can be used to
explicitly cast between pointers to different address spaces
(including adding/removing addresss spaces), while
static_cast/dynamic_cast/const_cast do not tolerate any changes in the
address space. C-style casts can add/remove/change address spaces
through the reinterpret_cast mechanism. Other non-CVR qualifiers
(e.g., Objective-C GC qualifiers) work similarly.
As part of this change, I tweaked the "casts away constness"
diagnostic to use the term "casts away qualifiers". The term
"constness" actually comes from the C++ standard, despite the fact
that removing "volatile" also falls under that category. In Clang, we
also have restrict, address spaces, ObjC GC attributes, etc., so the
more general "qualifiers" is clearer.
llvm-svn: 129583
2011-04-16 01:59:54 +08:00
( void ) reinterpret_cast < char * > ( s ) ; // expected-error {{reinterpret_cast from 'const STRING *' (aka 'char const (*)[10]') to 'char *' casts away qualifiers}}
2010-06-05 06:47:55 +08:00
( void ) reinterpret_cast < const STRING * > ( c ) ;
}