summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/reinterpret-cast.cpp
blob: f5262496c4b05505e1eea699163531be93ffc268 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding %s

#include <stdint.h>

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;
  (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
  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);
  intptr_t i = reinterpret_cast<intptr_t>(vp);
  (void)reinterpret_cast<float*>(i);
  fnptr fnp = reinterpret_cast<fnptr>(i);
  (void)reinterpret_cast<char>(fnp); // expected-error {{cast from pointer to smaller type 'char' loses information}}
  (void)reinterpret_cast<intptr_t>(fnp);
}

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*
  (void)reinterpret_cast<int*>(icp); // expected-error {{reinterpret_cast from 'const int *' to 'int *' casts away qualifiers}}
  // Invalid: T1*** -> T2 const* const**
  int const *const **icpcpp = reinterpret_cast<int const* const**>(ipppc); // expected-error {{reinterpret_cast from 'int ***' to 'const int *const **' casts away qualifiers}}
  // 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 &'}}
}

void memptrs()
{
  const int structure::*psi = 0;
  (void)reinterpret_cast<const float structure::*>(psi);
  (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'int structure::*' casts away qualifiers}}

  void (structure::*psf)() = 0;
  (void)reinterpret_cast<int (structure::*)()>(psf);

  (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'const int structure::*' to 'void (structure::*)()' is not allowed}}
  (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}

  // Cannot cast from integers to member pointers, not even the null pointer
  // literal.
  (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}}
}

namespace PR5545 {
// PR5545
class A;
class B;
void (A::*a)();
void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
}

// <rdar://problem/8018292>
void const_arrays() {
  typedef char STRING[10];
  const STRING *s;
  const char *c;

  (void)reinterpret_cast<char *>(s); // expected-error {{reinterpret_cast from 'const STRING *' (aka 'char const (*)[10]') to 'char *' casts away qualifiers}}
  (void)reinterpret_cast<const STRING *>(c);
}

namespace PR9564 {
  struct a { int a : 10; }; a x;
  int *y = &reinterpret_cast<int&>(x.a); // expected-error {{not allowed}}

  __attribute((ext_vector_type(4))) typedef float v4;
  float& w(v4 &a) { return reinterpret_cast<float&>(a[1]); } // expected-error {{not allowed}}
}
OpenPOWER on IntegriCloud