xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/google/readability-casting.cpp (revision 547685d9e4c64f6f5dadd0ac979ab312b9d395e7)
1*547685d9SPiotr Zegar // RUN: %check_clang_tidy -std=c++11-or-later %s google-readability-casting %t -- -- -fexceptions
289a1d03eSRichard 
g()389a1d03eSRichard bool g() { return false; }
489a1d03eSRichard 
589a1d03eSRichard enum Enum { Enum1 };
689a1d03eSRichard struct X {};
789a1d03eSRichard struct Y : public X {};
889a1d03eSRichard 
f(int a,double b,const char * cpc,const void * cpv,X * pX)989a1d03eSRichard void f(int a, double b, const char *cpc, const void *cpv, X *pX) {
1089a1d03eSRichard   const char *cpc2 = (const char*)cpc;
1189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type [google-readability-casting]
1289a1d03eSRichard   // CHECK-FIXES: const char *cpc2 = cpc;
1389a1d03eSRichard 
1489a1d03eSRichard   typedef const char *Typedef1;
1589a1d03eSRichard   typedef const char *Typedef2;
1689a1d03eSRichard   Typedef1 t1;
1789a1d03eSRichard   (Typedef2)t1;
1889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C-style casts are discouraged; use static_cast (if needed, the cast may be redundant) [google-readability-casting]
1989a1d03eSRichard   // CHECK-FIXES: {{^}}  static_cast<Typedef2>(t1);
2089a1d03eSRichard   (const char*)t1;
2189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
2289a1d03eSRichard   // CHECK-FIXES: {{^}}  static_cast<const char*>(t1);
2389a1d03eSRichard   (Typedef1)cpc;
2489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
2589a1d03eSRichard   // CHECK-FIXES: {{^}}  static_cast<Typedef1>(cpc);
2689a1d03eSRichard   (Typedef1)t1;
2789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant cast to the same type
2889a1d03eSRichard   // CHECK-FIXES: {{^}}  t1;
2989a1d03eSRichard 
3089a1d03eSRichard   char *pc = (char*)cpc;
3189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use const_cast [google-readability-casting]
3289a1d03eSRichard   // CHECK-FIXES: char *pc = const_cast<char*>(cpc);
3389a1d03eSRichard   typedef char Char;
3489a1d03eSRichard   Char *pChar = (Char*)pc;
3589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}}; use static_cast (if needed
3689a1d03eSRichard   // CHECK-FIXES: {{^}}  Char *pChar = static_cast<Char*>(pc);
3789a1d03eSRichard 
3889a1d03eSRichard   (Char)*cpc;
3989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
4089a1d03eSRichard   // CHECK-FIXES: {{^}}  static_cast<Char>(*cpc);
4189a1d03eSRichard 
4289a1d03eSRichard   (char)*pChar;
4389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
4489a1d03eSRichard   // CHECK-FIXES: {{^}}  static_cast<char>(*pChar);
4589a1d03eSRichard 
4689a1d03eSRichard   (const char*)cpv;
4789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast [
4889a1d03eSRichard   // CHECK-FIXES: static_cast<const char*>(cpv);
4989a1d03eSRichard 
5089a1d03eSRichard   char *pc2 = (char*)(cpc + 33);
5189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
5289a1d03eSRichard   // CHECK-FIXES: char *pc2 = const_cast<char*>(cpc + 33);
5389a1d03eSRichard 
5489a1d03eSRichard   const char &crc = *cpc;
5589a1d03eSRichard   char &rc = (char&)crc;
5689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}}; use const_cast [
5789a1d03eSRichard   // CHECK-FIXES: char &rc = const_cast<char&>(crc);
5889a1d03eSRichard 
5989a1d03eSRichard   char &rc2 = (char&)*cpc;
6089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
6189a1d03eSRichard   // CHECK-FIXES: char &rc2 = const_cast<char&>(*cpc);
6289a1d03eSRichard 
6389a1d03eSRichard   char ** const* const* ppcpcpc;
6489a1d03eSRichard   char ****ppppc = (char****)ppcpcpc;
6589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: {{.*}}; use const_cast [
6689a1d03eSRichard   // CHECK-FIXES: char ****ppppc = const_cast<char****>(ppcpcpc);
6789a1d03eSRichard 
6889a1d03eSRichard   char ***pppc = (char***)*(ppcpcpc);
6989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}}; use const_cast [
7089a1d03eSRichard   // CHECK-FIXES: char ***pppc = const_cast<char***>(*(ppcpcpc));
7189a1d03eSRichard 
7289a1d03eSRichard   char ***pppc2 = (char***)(*ppcpcpc);
7389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}; use const_cast [
7489a1d03eSRichard   // CHECK-FIXES: char ***pppc2 = const_cast<char***>(*ppcpcpc);
7589a1d03eSRichard 
7689a1d03eSRichard   char *pc5 = (char*)(const char*)(cpv);
7789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
7889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}}; use static_cast [
7989a1d03eSRichard   // CHECK-FIXES: char *pc5 = const_cast<char*>(static_cast<const char*>(cpv));
8089a1d03eSRichard 
8189a1d03eSRichard   int b1 = (int)b;
8289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast [
8389a1d03eSRichard   // CHECK-FIXES: int b1 = static_cast<int>(b);
8489a1d03eSRichard   b1 = (const int&)b;
8589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
8689a1d03eSRichard   // CHECK-FIXES: b1 = (const int&)b;
8789a1d03eSRichard 
8889a1d03eSRichard   b1 = (int) b;
8989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
9089a1d03eSRichard   // CHECK-FIXES: b1 = static_cast<int>(b);
9189a1d03eSRichard 
9289a1d03eSRichard   b1 = (int)         b;
9389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
9489a1d03eSRichard   // CHECK-FIXES: b1 = static_cast<int>(b);
9589a1d03eSRichard 
9689a1d03eSRichard   b1 = (int) (b);
9789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
9889a1d03eSRichard   // CHECK-FIXES: b1 = static_cast<int>(b);
9989a1d03eSRichard 
10089a1d03eSRichard   b1 = (int)         (b);
10189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
10289a1d03eSRichard   // CHECK-FIXES: b1 = static_cast<int>(b);
10389a1d03eSRichard 
10489a1d03eSRichard   Y *pB = (Y*)pX;
10589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
10689a1d03eSRichard   Y &rB = (Y&)*pX;
10789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
10889a1d03eSRichard 
10989a1d03eSRichard   const char *pc3 = (const char*)cpv;
11089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}}; use static_cast [
11189a1d03eSRichard   // CHECK-FIXES: const char *pc3 = static_cast<const char*>(cpv);
11289a1d03eSRichard 
11389a1d03eSRichard   char *pc4 = (char*)cpv;
11489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
11589a1d03eSRichard   // CHECK-FIXES: char *pc4 = (char*)cpv;
11689a1d03eSRichard 
11789a1d03eSRichard   b1 = (int)Enum1;
11889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast [
11989a1d03eSRichard   // CHECK-FIXES: b1 = static_cast<int>(Enum1);
12089a1d03eSRichard 
12189a1d03eSRichard   Enum e = (Enum)b1;
12289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast [
12389a1d03eSRichard   // CHECK-FIXES: Enum e = static_cast<Enum>(b1);
12489a1d03eSRichard 
12589a1d03eSRichard   e = (Enum)Enum1;
12689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
12789a1d03eSRichard   // CHECK-FIXES: {{^}}  e = Enum1;
12889a1d03eSRichard 
12989a1d03eSRichard   e = (Enum)e;
13089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
13189a1d03eSRichard   // CHECK-FIXES: {{^}}  e = e;
13289a1d03eSRichard 
13389a1d03eSRichard   e = (Enum)           e;
13489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
13589a1d03eSRichard   // CHECK-FIXES: {{^}}  e = e;
13689a1d03eSRichard 
13789a1d03eSRichard   e = (Enum)           (e);
13889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
13989a1d03eSRichard   // CHECK-FIXES: {{^}}  e = (e);
14089a1d03eSRichard 
14189a1d03eSRichard   static const int kZero = 0;
14289a1d03eSRichard   (int)kZero;
14389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant cast to the same type
14489a1d03eSRichard   // CHECK-FIXES: {{^}}  kZero;
14589a1d03eSRichard 
14689a1d03eSRichard   int b2 = static_cast<double>(b);
14789a1d03eSRichard   int b3 = b;
14889a1d03eSRichard   double aa = a;
14989a1d03eSRichard   (void)aa;
15089a1d03eSRichard   return (void)g();
15189a1d03eSRichard }
15289a1d03eSRichard 
15389a1d03eSRichard template <typename T>
template_function(T t,int n)15489a1d03eSRichard void template_function(T t, int n) {
15589a1d03eSRichard   int i = (int)t;
15689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
15789a1d03eSRichard   // CHECK-FIXES: int i = (int)t;
15889a1d03eSRichard   int j = (int)n;
15989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type
16089a1d03eSRichard   // CHECK-FIXES: int j = n;
16189a1d03eSRichard }
16289a1d03eSRichard 
16389a1d03eSRichard template <typename T>
16489a1d03eSRichard struct TemplateStruct {
fTemplateStruct16589a1d03eSRichard   void f(T t, int n) {
16689a1d03eSRichard     int k = (int)t;
16789a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast
16889a1d03eSRichard     // CHECK-FIXES: int k = (int)t;
16989a1d03eSRichard     int l = (int)n;
17089a1d03eSRichard     // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant cast to the same type
17189a1d03eSRichard     // CHECK-FIXES: int l = n;
17289a1d03eSRichard   }
17389a1d03eSRichard };
17489a1d03eSRichard 
test_templates()17589a1d03eSRichard void test_templates() {
17689a1d03eSRichard   template_function(1, 42);
17789a1d03eSRichard   template_function(1.0, 42);
17889a1d03eSRichard   TemplateStruct<int>().f(1, 42);
17989a1d03eSRichard   TemplateStruct<double>().f(1.0, 42);
18089a1d03eSRichard }
18189a1d03eSRichard 
18289a1d03eSRichard extern "C" {
extern_c_code(const char * cpc)18389a1d03eSRichard void extern_c_code(const char *cpc) {
18489a1d03eSRichard   const char *cpc2 = (const char*)cpc;
18589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type
18689a1d03eSRichard   // CHECK-FIXES: const char *cpc2 = cpc;
18789a1d03eSRichard   char *pc = (char*)cpc;
18889a1d03eSRichard }
18989a1d03eSRichard }
19089a1d03eSRichard 
19189a1d03eSRichard #define CAST(type, value) (type)(value)
macros(double d)19289a1d03eSRichard void macros(double d) {
19389a1d03eSRichard   int i = CAST(int, d);
19489a1d03eSRichard }
19589a1d03eSRichard 
19689a1d03eSRichard enum E { E1 = 1 };
19789a1d03eSRichard template <E e>
19889a1d03eSRichard struct A {
19989a1d03eSRichard   // Usage of template argument e = E1 is represented as (E)1 in the AST for
20089a1d03eSRichard   // some reason. We have a special treatment of this case to avoid warnings
20189a1d03eSRichard   // here.
20289a1d03eSRichard   static const E ee = e;
20389a1d03eSRichard };
20489a1d03eSRichard struct B : public A<E1> {};
20589a1d03eSRichard 
20689a1d03eSRichard 
20789a1d03eSRichard void overloaded_function();
20889a1d03eSRichard void overloaded_function(int);
20989a1d03eSRichard 
21089a1d03eSRichard template<typename Fn>
g(Fn fn)21189a1d03eSRichard void g(Fn fn) {
21289a1d03eSRichard   fn();
21389a1d03eSRichard }
21489a1d03eSRichard 
function_casts()21589a1d03eSRichard void function_casts() {
21689a1d03eSRichard   typedef void (*FnPtrVoid)();
21789a1d03eSRichard   typedef void (&FnRefVoid)();
21889a1d03eSRichard   typedef void (&FnRefInt)(int);
21989a1d03eSRichard 
22089a1d03eSRichard   g((void (*)())overloaded_function);
22189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
22289a1d03eSRichard   // CHECK-FIXES: g(static_cast<void (*)()>(overloaded_function));
22389a1d03eSRichard   g((void (*)())&overloaded_function);
22489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
22589a1d03eSRichard   // CHECK-FIXES: g(static_cast<void (*)()>(&overloaded_function));
22689a1d03eSRichard   g((void (&)())overloaded_function);
22789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
22889a1d03eSRichard   // CHECK-FIXES: g(static_cast<void (&)()>(overloaded_function));
22989a1d03eSRichard 
23089a1d03eSRichard   g((FnPtrVoid)overloaded_function);
23189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
23289a1d03eSRichard   // CHECK-FIXES: g(static_cast<FnPtrVoid>(overloaded_function));
23389a1d03eSRichard   g((FnPtrVoid)&overloaded_function);
23489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
23589a1d03eSRichard   // CHECK-FIXES: g(static_cast<FnPtrVoid>(&overloaded_function));
23689a1d03eSRichard   g((FnRefVoid)overloaded_function);
23789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
23889a1d03eSRichard   // CHECK-FIXES: g(static_cast<FnRefVoid>(overloaded_function));
23989a1d03eSRichard 
24089a1d03eSRichard   FnPtrVoid fn0 = (void (*)())&overloaded_function;
24189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
24289a1d03eSRichard   // CHECK-FIXES: FnPtrVoid fn0 = static_cast<void (*)()>(&overloaded_function);
24389a1d03eSRichard   FnPtrVoid fn1 = (void (*)())overloaded_function;
24489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
24589a1d03eSRichard   // CHECK-FIXES: FnPtrVoid fn1 = static_cast<void (*)()>(overloaded_function);
24689a1d03eSRichard   FnPtrVoid fn1a = (FnPtrVoid)overloaded_function;
24789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: C-style casts are discouraged; use static_cast [
24889a1d03eSRichard   // CHECK-FIXES: FnPtrVoid fn1a = static_cast<FnPtrVoid>(overloaded_function);
24989a1d03eSRichard   FnRefInt fn2 = (void (&)(int))overloaded_function;
25089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: C-style casts are discouraged; use static_cast [
25189a1d03eSRichard   // CHECK-FIXES: FnRefInt fn2 = static_cast<void (&)(int)>(overloaded_function);
25289a1d03eSRichard   auto fn3 = (void (*)())&overloaded_function;
25389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
25489a1d03eSRichard   // CHECK-FIXES: auto fn3 = static_cast<void (*)()>(&overloaded_function);
25589a1d03eSRichard   auto fn4 = (void (*)())overloaded_function;
25689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
25789a1d03eSRichard   // CHECK-FIXES: auto fn4 = static_cast<void (*)()>(overloaded_function);
25889a1d03eSRichard   auto fn5 = (void (&)(int))overloaded_function;
25989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
26089a1d03eSRichard   // CHECK-FIXES: auto fn5 = static_cast<void (&)(int)>(overloaded_function);
26189a1d03eSRichard 
26289a1d03eSRichard   void (*fn6)() = (void (*)())&overloaded_function;
26389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
26489a1d03eSRichard   // CHECK-FIXES: void (*fn6)() = static_cast<void (*)()>(&overloaded_function);
26589a1d03eSRichard   void (*fn7)() = (void (*)())overloaded_function;
26689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
26789a1d03eSRichard   // CHECK-FIXES: void (*fn7)() = static_cast<void (*)()>(overloaded_function);
26889a1d03eSRichard   void (*fn8)() = (FnPtrVoid)overloaded_function;
26989a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
27089a1d03eSRichard   // CHECK-FIXES: void (*fn8)() = static_cast<FnPtrVoid>(overloaded_function);
27189a1d03eSRichard   void (&fn9)(int) = (void (&)(int))overloaded_function;
27289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: C-style casts are discouraged; use static_cast [
27389a1d03eSRichard   // CHECK-FIXES: void (&fn9)(int) = static_cast<void (&)(int)>(overloaded_function);
27489a1d03eSRichard 
27589a1d03eSRichard   void (*correct1)() = static_cast<void (*)()>(overloaded_function);
27689a1d03eSRichard   FnPtrVoid correct2 = static_cast<void (*)()>(&overloaded_function);
27789a1d03eSRichard   FnRefInt correct3 = static_cast<void (&)(int)>(overloaded_function);
27889a1d03eSRichard }
27989a1d03eSRichard 
28089a1d03eSRichard struct S {
28189a1d03eSRichard     S(const char *);
28289a1d03eSRichard };
28389a1d03eSRichard struct ConvertibleToS {
28489a1d03eSRichard   operator S() const;
28589a1d03eSRichard };
28689a1d03eSRichard struct ConvertibleToSRef {
28789a1d03eSRichard   operator const S&() const;
28889a1d03eSRichard };
28989a1d03eSRichard 
conversions()29089a1d03eSRichard void conversions() {
29189a1d03eSRichard   //auto s1 = (const S&)"";
29289a1d03eSRichard   // C HECK-MESSAGES: :[[@LINE-1]]:10: warning: C-style casts are discouraged; use static_cast [
29389a1d03eSRichard   // C HECK-FIXES: S s1 = static_cast<const S&>("");
29489a1d03eSRichard   auto s2 = (S)"";
29589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
29689a1d03eSRichard   // CHECK-FIXES: auto s2 = S("");
29789a1d03eSRichard   auto s2a = (struct S)"";
29889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
29989a1d03eSRichard   // CHECK-FIXES: auto s2a = static_cast<struct S>("");
30089a1d03eSRichard   auto s2b = (const S)"";
30189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
30289a1d03eSRichard   // FIXME: This should be constructor call syntax: S("").
30389a1d03eSRichard   // CHECK-FIXES: auto s2b = static_cast<const S>("");
30489a1d03eSRichard   ConvertibleToS c;
30589a1d03eSRichard   auto s3 = (const S&)c;
30689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [
30789a1d03eSRichard   // CHECK-FIXES: auto s3 = (const S&)c;
30889a1d03eSRichard   // FIXME: This should be a static_cast.
30989a1d03eSRichard   // C HECK-FIXES: auto s3 = static_cast<const S&>(c);
31089a1d03eSRichard   auto s4 = (S)c;
31189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
31289a1d03eSRichard   // CHECK-FIXES: auto s4 = S(c);
31389a1d03eSRichard   ConvertibleToSRef cr;
31489a1d03eSRichard   auto s5 = (const S&)cr;
31589a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [
31689a1d03eSRichard   // CHECK-FIXES: auto s5 = (const S&)cr;
31789a1d03eSRichard   // FIXME: This should be a static_cast.
31889a1d03eSRichard   // C HECK-FIXES: auto s5 = static_cast<const S&>(cr);
31989a1d03eSRichard   auto s6 = (S)cr;
32089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
32189a1d03eSRichard   // CHECK-FIXES: auto s6 = S(cr);
32289a1d03eSRichard }
32389a1d03eSRichard 
32489a1d03eSRichard template <class T>
functional_cast_template(float i)325b0b491d4SPiotr Zegar T functional_cast_template(float i) {
32689a1d03eSRichard   return T(i);
32789a1d03eSRichard }
32889a1d03eSRichard 
32989a1d03eSRichard struct S2 {
33089a1d03eSRichard   S2(float);
33189a1d03eSRichard };
33289a1d03eSRichard using T = S2;
33389a1d03eSRichard using U = S2 &;
33489a1d03eSRichard 
functional_casts()33589a1d03eSRichard void functional_casts() {
33689a1d03eSRichard   float x = 1.5F;
33789a1d03eSRichard   auto y = int(x);
33889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: C-style casts are discouraged; use static_cast
33989a1d03eSRichard   // CHECK-FIXES: auto y = static_cast<int>(x);
34089a1d03eSRichard 
34189a1d03eSRichard #pragma clang diagnostic push
34289a1d03eSRichard #pragma clang diagnostic ignored "-Wc++11-narrowing"
34389a1d03eSRichard   // This if fine, compiler will warn about implicit conversions with brace initialization
34489a1d03eSRichard   auto z = int{x};
34589a1d03eSRichard #pragma clang diagnostic pop
34689a1d03eSRichard 
34789a1d03eSRichard   // Functional casts are allowed if S is of class type
34889a1d03eSRichard   const char *str = "foo";
34989a1d03eSRichard   auto s = S(str);
35089a1d03eSRichard 
35189a1d03eSRichard   // Functional casts in template functions
352b0b491d4SPiotr Zegar   functional_cast_template<S2>(x);
353b0b491d4SPiotr Zegar   functional_cast_template<int>(x);
35489a1d03eSRichard 
35589a1d03eSRichard   // New expressions are not functional casts
35689a1d03eSRichard   auto w = new int(x);
35789a1d03eSRichard 
35889a1d03eSRichard   // Typedefs
35989a1d03eSRichard   S2 t = T(x); // OK, constructor call
36089a1d03eSRichard   S2 u = U(x); // NOK, it's a reinterpret_cast in disguise
36189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast
362b0b491d4SPiotr Zegar 
363b0b491d4SPiotr Zegar   throw S2(5.0f);
36489a1d03eSRichard }
365