reinterpret-cast.cpp revision 52647c63c3cbdf0c87fe8db3ef6f475bfd49725d
1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
22f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor
3f1cd5e5c85f2ad433874310d826c1860a262909cSean Hunt#include <stdint.h>
4f1cd5e5c85f2ad433874310d826c1860a262909cSean Hunt
52f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorenum test { testval = 1 };
62f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorstruct structure { int m; };
72f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregortypedef void (*fnptr)();
82f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor
92f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor// Test the conversion to self.
102f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorvoid self_conversion()
112f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor{
122f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // T*->T* is allowed, T->T in general not.
132f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  int i = 0;
142f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<int>(i); // expected-error {{reinterpret_cast from 'int' to 'int' is not allowed}}
152f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  structure s;
167c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
172f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  int *pi = 0;
182f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<int*>(pi);
192f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor}
202f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor
212f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor// Test conversion between pointer and integral types, as in /3 and /4.
222f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorvoid integral_conversion()
232f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor{
242f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  void *vp = reinterpret_cast<void*>(testval);
25f1cd5e5c85f2ad433874310d826c1860a262909cSean Hunt  intptr_t i = reinterpret_cast<intptr_t>(vp);
26f1cd5e5c85f2ad433874310d826c1860a262909cSean Hunt  (void)reinterpret_cast<float*>(i);
27f1cd5e5c85f2ad433874310d826c1860a262909cSean Hunt  fnptr fnp = reinterpret_cast<fnptr>(i);
282f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<char>(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
29f1cd5e5c85f2ad433874310d826c1860a262909cSean Hunt  (void)reinterpret_cast<intptr_t>(fnp);
302f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor}
312f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor
322f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorvoid pointer_conversion()
332f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor{
342f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  int *p1 = 0;
352f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  float *p2 = reinterpret_cast<float*>(p1);
362f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  structure *p3 = reinterpret_cast<structure*>(p2);
372f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  typedef int **ppint;
382f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  ppint *deep = reinterpret_cast<ppint*>(p3);
392f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<fnptr*>(deep);
402f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor}
412f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor
422f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorvoid constness()
432f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor{
442f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  int ***const ipppc = 0;
452f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // Valid: T1* -> T2 const*
462f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  int const *icp = reinterpret_cast<int const*>(ipppc);
472f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // Invalid: T1 const* -> T2*
482f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'int const *' to 'int *' casts away constness}}
492f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // Invalid: T1*** -> T2 const* const**
50a873dfc9e7314681bb37efd9ab185045de121e43Douglas Gregor  int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'int const *const **' casts away constness}}
512f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // Valid: T1* -> T2*
522f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  int *ip = reinterpret_cast<int*>(icpcpp);
532f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // Valid: T* -> T const*
542f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<int const*>(ip);
552f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // Valid: T*** -> T2 const* const* const*
562f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<int const* const* const*>(ipppc);
572f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor}
582f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor
592f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorvoid fnptrs()
602f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor{
612f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  typedef int (*fnptr2)(int);
622f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  fnptr fp = 0;
632f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<fnptr2>(fp);
642f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  void *vp = reinterpret_cast<void*>(fp);
652f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<fnptr>(vp);
662f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor}
672f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor
682f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregorvoid refs()
692f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor{
702f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  long l = 0;
712f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  char &c = reinterpret_cast<char&>(l);
722f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  // Bad: from rvalue
732f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor  (void)reinterpret_cast<int&>(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}}
742f639b9f3c6b081f076d2ac6d75115ce44bfa249Douglas Gregor}
75db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl
76db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redlvoid memptrs()
77db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl{
78db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl  const int structure::*psi = 0;
79db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl  (void)reinterpret_cast<const float structure::*>(psi);
807c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'int structure::*' casts away constness}}
81db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl
82db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl  void (structure::*psf)() = 0;
83db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl  (void)reinterpret_cast<int (structure::*)()>(psf);
84db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl
857c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'void (structure::*)()' is not allowed}}
867c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
87db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl
88db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl  // Cannot cast from integers to member pointers, not even the null pointer
89db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl  // literal.
907c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
917c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
92db64728e69a45b89870ede13944a934d3c2ed12aSebastian Redl}
9376d69bb7f984c390f90504a06dfc7485387ffdd7Sebastian Redl
9452647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlssonnamespace PR5545 {
9576d69bb7f984c390f90504a06dfc7485387ffdd7Sebastian Redl// PR5545
9676d69bb7f984c390f90504a06dfc7485387ffdd7Sebastian Redlclass A;
9776d69bb7f984c390f90504a06dfc7485387ffdd7Sebastian Redlclass B;
9876d69bb7f984c390f90504a06dfc7485387ffdd7Sebastian Redlvoid (A::*a)();
9976d69bb7f984c390f90504a06dfc7485387ffdd7Sebastian Redlvoid (B::*b)() = reinterpret_cast<void (B::*)()>(a);
10052647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson}
10152647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson
10252647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson// <rdar://problem/8018292>
10352647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlssonvoid const_arrays() {
10452647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson  typedef char STRING[10];
10552647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson  const STRING *s;
10652647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson  const char *c;
10752647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson
10852647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson  (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'STRING const *' (aka 'char const (*)[10]') to 'char *' casts away constness}}
10952647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson  (void)reinterpret_cast<const STRING *>(c);
11052647c63c3cbdf0c87fe8db3ef6f475bfd49725dAnders Carlsson}
111