Clang Project

clang_source_code/test/SemaCXX/warn-cast-qual.cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -Wcast-qual -verify %s
2
3#include <stdint.h>
4
5// do *NOT* warn on const_cast<>()
6// use clang-tidy's cppcoreguidelines-pro-type-const-cast for that.
7void foo_ptr() {
8  const char *const ptr = 0;
9  char *t0 = const_cast<char *>(ptr); // no warning
10
11  volatile char *ptr2 = 0;
12  char *t1 = const_cast<char *>(ptr2); // no warning
13
14  const volatile char *ptr3 = 0;
15  char *t2 = const_cast<char *>(ptr3); // no warning
16}
17
18void cstr() {
19  void* p0 = (void*)(const void*)"txt"; // expected-warning {{cast from 'const void *' to 'void *' drops const qualifier}}
20  void* p1 = (void*)"txt"; // FIXME
21  char* p2 = (char*)"txt"; // expected-warning {{cast from 'const char *' to 'char *' drops const qualifier}}
22}
23
24void foo_0() {
25  const int a = 0;
26
27  const int &a0 = a;              // no warning
28  const int &a1 = (const int &)a; // no warning
29
30  int &a2 = (int &)a;                      // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
31  const int &a3 = (int &)a;                // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
32  int &a4 = (int &)((const int &)a);       // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
33  int &a5 = (int &)((int &)a);             // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
34  const int &a6 = (int &)((int &)a);       // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
35  const int &a7 = (int &)((const int &)a); // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
36  const int &a8 = (const int &)((int &)a); // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
37}
38
39void foo_1() {
40  volatile int a = 0;
41
42  volatile int &a0 = a;                 // no warning
43  volatile int &a1 = (volatile int &)a; // no warning
44
45  int &a2 = (int &)a;                            // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}}
46  volatile int &a3 = (int &)a;                   // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}}
47  int &a4 = (int &)((volatile int &)a);          // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}}
48  int &a5 = (int &)((int &)a);                   // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}}
49  volatile int &a6 = (int &)((int &)a);          // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}}
50  volatile int &a7 = (int &)((volatile int &)a); // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}}
51  volatile int &a8 = (volatile int &)((int &)a); // expected-warning {{cast from 'volatile int' to 'int &' drops volatile qualifier}}
52}
53
54void foo_2() {
55  const volatile int a = 0;
56
57  const volatile int &a0 = a;                       // no warning
58  const volatile int &a1 = (const volatile int &)a; // no warning
59
60  int &a2 = (int &)a;                                        // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}}
61  const volatile int &a3 = (int &)a;                         // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}}
62  int &a4 = (int &)((const volatile int &)a);                // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}}
63  int &a5 = (int &)((int &)a);                               // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}}
64  const volatile int &a6 = (int &)((int &)a);                // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}}
65  const volatile int &a7 = (int &)((const volatile int &)a); // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}}
66  const volatile int &a8 = (const volatile int &)((int &)a); // expected-warning {{cast from 'const volatile int' to 'int &' drops const and volatile qualifiers}}
67}
68
69void bar_0() {
70  const int *_a = 0;
71  const int **a = &_a;
72
73  int **a0 = (int **)((const int **)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
74  int **a1 = (int **)((int **)a);       // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
75
76  // const int **a2 = (int **)((int **)a);
77  // const int **a3 = (int **)((const int **)a);
78
79  const int **a4 = (const int **)((int **)a);        // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} expected-warning {{cast from 'int **' to 'const int **' must have all intermediate pointers const qualified to be safe}}
80  const int **a5 = (const int **)((const int **)a); // no warning
81}
82
83void bar_1() {
84  const int *_a = 0;
85  const int *&a = _a;
86
87  int *&a0 = (int *&)((const int *&)a); // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
88  int *&a1 = (int *&)((int *&)a);       // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
89
90  // const int *&a2 = (int *&)((int *&)a);
91  // const int *&a3 = (int *&)((const int *&)a);
92
93  const int *&a4 = (const int *&)((int *&)a);        // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}} expected-warning {{cast from 'int *' to 'const int *&' must have all intermediate pointers const qualified to be safe}}
94  const int *&a5 = (const int *&)((const int *&)a); // no warning
95}
96
97void baz_0() {
98  struct C {
99    void A() {}
100    void B() const {}
101  };
102
103  const C S;
104  S.B();
105
106  ((C &)S).B(); // expected-warning {{cast from 'const C' to 'C &' drops const qualifier}}
107  ((C &)S).A(); // expected-warning {{cast from 'const C' to 'C &' drops const qualifier}}
108
109  ((C *)&S)->B(); // expected-warning {{cast from 'const C *' to 'C *' drops const qualifier}}
110  ((C *)&S)->A(); // expected-warning {{cast from 'const C *' to 'C *' drops const qualifier}}
111}
112
113void baz_1() {
114  struct C {
115    const int a;
116    int b;
117
118    C() : a(0) {}
119  };
120
121  {
122    C S;
123    S.b = 0;
124
125    (int &)(S.a) = 0; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
126    (int &)(S.b) = 0; // no warning
127
128    *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
129    *(int *)(&S.b) = 0; // no warning
130  }
131  {
132    const C S;
133
134    (int &)(S.a) = 0; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
135    (int &)(S.b) = 0; // expected-warning {{cast from 'const int' to 'int &' drops const qualifier}}
136
137    *(int *)(&S.a) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
138    *(int *)(&S.b) = 0; // expected-warning {{cast from 'const int *' to 'int *' drops const qualifier}}
139  }
140}
141