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