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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
// RUN: %check_clang_tidy %s google-readability-casting %t
bool g() { return false; }
enum Enum { Enum1 };
struct X {};
struct Y : public X {};
void f(int a, double b, const char *cpc, const void *cpv, X *pX) {
const char *cpc2 = (const char*)cpc;
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type [google-readability-casting]
// CHECK-FIXES: const char *cpc2 = cpc;
typedef const char *Typedef1;
typedef const char *Typedef2;
Typedef1 t1;
(Typedef2)t1;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: possibly redundant cast between typedefs of the same type [google-readability-casting]
// CHECK-FIXES: {{^}} (Typedef2)t1;
(const char*)t1;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: possibly redundant cast {{.*}}
// CHECK-FIXES: {{^}} (const char*)t1;
(Typedef1)cpc;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: possibly redundant cast {{.*}}
// CHECK-FIXES: {{^}} (Typedef1)cpc;
(Typedef1)t1;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant cast to the same type
// CHECK-FIXES: {{^}} t1;
char *pc = (char*)cpc;
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use const_cast [google-readability-casting]
// CHECK-FIXES: char *pc = const_cast<char*>(cpc);
char *pc2 = (char*)(cpc + 33);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast {{.*}}
// CHECK-FIXES: char *pc2 = const_cast<char*>(cpc + 33);
const char &crc = *cpc;
char &rc = (char&)crc;
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}}; use const_cast {{.*}}
// CHECK-FIXES: char &rc = const_cast<char&>(crc);
char &rc2 = (char&)*cpc;
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast {{.*}}
// CHECK-FIXES: char &rc2 = const_cast<char&>(*cpc);
char ** const* const* ppcpcpc;
char ****ppppc = (char****)ppcpcpc;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: {{.*}}; use const_cast {{.*}}
// CHECK-FIXES: char ****ppppc = const_cast<char****>(ppcpcpc);
char ***pppc = (char***)*(ppcpcpc);
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}}; use const_cast {{.*}}
// CHECK-FIXES: char ***pppc = const_cast<char***>(*(ppcpcpc));
char ***pppc2 = (char***)(*ppcpcpc);
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}; use const_cast {{.*}}
// CHECK-FIXES: char ***pppc2 = const_cast<char***>(*ppcpcpc);
char *pc5 = (char*)(const char*)(cpv);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast {{.*}}
// CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}}; use reinterpret_cast {{.*}}
// CHECK-FIXES: char *pc5 = const_cast<char*>(reinterpret_cast<const char*>(cpv));
int b1 = (int)b;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast {{.*}}
// CHECK-FIXES: int b1 = static_cast<int>(b);
Y *pB = (Y*)pX;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast {{.*}}
Y &rB = (Y&)*pX;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast {{.*}}
const char *pc3 = (const char*)cpv;
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}}; use reinterpret_cast {{.*}}
// CHECK-FIXES: const char *pc3 = reinterpret_cast<const char*>(cpv);
char *pc4 = (char*)cpv;
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast {{.*}}
// CHECK-FIXES: char *pc4 = (char*)cpv;
b1 = (int)Enum1;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
// CHECK-FIXES: b1 = static_cast<int>(Enum1);
Enum e = (Enum)b1;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast {{.*}}
// CHECK-FIXES: Enum e = static_cast<Enum>(b1);
// CHECK-MESSAGES-NOT: warning:
int b2 = int(b);
int b3 = static_cast<double>(b);
int b4 = b;
double aa = a;
(void)b2;
return (void)g();
}
template <typename T>
void template_function(T t, int n) {
int i = (int)t;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast {{.*}}
// CHECK-FIXES: int i = (int)t;
int j = (int)n;
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type
// CHECK-FIXES: int j = n;
}
template <typename T>
struct TemplateStruct {
void f(T t, int n) {
int k = (int)t;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast
// CHECK-FIXES: int k = (int)t;
int l = (int)n;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant cast to the same type
// CHECK-FIXES: int l = n;
}
};
void test_templates() {
template_function(1, 42);
template_function(1.0, 42);
TemplateStruct<int>().f(1, 42);
TemplateStruct<double>().f(1.0, 42);
}
extern "C" {
void extern_c_code(const char *cpc) {
const char *cpc2 = (const char*)cpc;
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type
// CHECK-FIXES: const char *cpc2 = cpc;
char *pc = (char*)cpc;
}
}
#define CAST(type, value) (type)(value)
void macros(double d) {
int i = CAST(int, d);
}
enum E { E1 = 1 };
template <E e>
struct A {
// Usage of template argument e = E1 is represented as (E)1 in the AST for
// some reason. We have a special treatment of this case to avoid warnings
// here.
static const E ee = e;
};
struct B : public A<E1> {};
|