1 // RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-cstyle-cast %t
2 
reinterpretcast()3 void reinterpretcast() {
4   int i = 0;
5   void *j;
6   j = (int*)j;
7   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]
8 }
9 
constcast()10 void constcast() {
11   int* i;
12   const int* j;
13   i = (int*)j;
14   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to cast away constness
15   j = (const int*)i; // OK, const added
16   (void)j; // OK, not a const_cast
17 }
18 
const_and_reinterpret()19 void const_and_reinterpret() {
20   int* i;
21   const void* j;
22   i = (int*)j;
23   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to convert between unrelated types
24 }
25 
26 class Base {
27 };
28 
29 class Derived : public Base {
30 };
31 
32 class Base2 {
33 };
34 
35 class MultiDerived : public Base, public Base2 {
36 };
37 
38 class PolymorphicBase {
39 public:
40   virtual ~PolymorphicBase();
41 };
42 
43 class PolymorphicDerived : public PolymorphicBase {
44 };
45 
46 class PolymorphicMultiDerived : public Base, public PolymorphicBase {
47 };
48 
pointers()49 void pointers() {
50 
51   auto P0 = (Derived*)new Base();
52   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
53 
54   const Base* B0;
55   auto PC0 = (const Derived*)(B0);
56   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class
57 
58   auto P1 = (Base*)new Derived(); // OK, upcast to a public base
59   auto P2 = (Base*)new MultiDerived(); // OK, upcast to a public base
60   auto P3 = (Base2*)new MultiDerived(); // OK, upcast to a public base
61 }
62 
pointers_polymorphic()63 void pointers_polymorphic() {
64 
65   auto PP0 = (PolymorphicDerived*)new PolymorphicBase();
66   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
67   // CHECK-FIXES: auto PP0 = dynamic_cast<PolymorphicDerived*>(new PolymorphicBase());
68 
69   const PolymorphicBase* B0;
70   auto PPC0 = (const PolymorphicDerived*)B0;
71   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
72   // CHECK-FIXES: auto PPC0 = dynamic_cast<const PolymorphicDerived*>(B0);
73 
74 
75   auto B1 = (PolymorphicBase*)new PolymorphicDerived(); // OK, upcast to a public base
76   auto B2 = (PolymorphicBase*)new PolymorphicMultiDerived(); // OK, upcast to a public base
77   auto B3 = (Base*)new PolymorphicMultiDerived(); // OK, upcast to a public base
78 }
79 
arrays()80 void arrays() {
81   Base ArrayOfBase[10];
82   auto A0 = (Derived*)ArrayOfBase;
83   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
84 }
85 
arrays_polymorphic()86 void arrays_polymorphic() {
87   PolymorphicBase ArrayOfPolymorphicBase[10];
88   auto AP0 = (PolymorphicDerived*)ArrayOfPolymorphicBase;
89   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
90   // CHECK-FIXES: auto AP0 = dynamic_cast<PolymorphicDerived*>(ArrayOfPolymorphicBase);
91 }
92 
references()93 void references() {
94   Base B0;
95   auto R0 = (Derived&)B0;
96   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
97   Base& RefToBase = B0;
98   auto R1 = (Derived&)RefToBase;
99   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
100 
101   const Base& ConstRefToBase = B0;
102   auto RC1 = (const Derived&)ConstRefToBase;
103   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class
104 
105 
106   Derived RD1;
107   auto R2 = (Base&)RD1; // OK, upcast to a public base
108 }
109 
references_polymorphic()110 void references_polymorphic() {
111   PolymorphicBase B0;
112   auto RP0 = (PolymorphicDerived&)B0;
113   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
114   // CHECK-FIXES: auto RP0 = dynamic_cast<PolymorphicDerived&>(B0);
115 
116   PolymorphicBase& RefToPolymorphicBase = B0;
117   auto RP1 = (PolymorphicDerived&)RefToPolymorphicBase;
118   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
119   // CHECK-FIXES: auto RP1 = dynamic_cast<PolymorphicDerived&>(RefToPolymorphicBase);
120 
121   const PolymorphicBase& ConstRefToPolymorphicBase = B0;
122   auto RPC2 = (const PolymorphicDerived&)(ConstRefToPolymorphicBase);
123   // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
124   // CHECK-FIXES: auto RPC2 = dynamic_cast<const PolymorphicDerived&>(ConstRefToPolymorphicBase);
125 
126   PolymorphicDerived d1;
127   auto RP2 = (PolymorphicBase&)d1; // OK, upcast to a public base
128 }
129 
130 template<class B, class D>
templ()131 void templ() {
132   auto B0 = (B*)new D();
133 }
134 
templ_bad_call()135 void templ_bad_call() {
136   templ<Derived, Base>(); //FIXME: this should trigger a warning
137 }
138 
templ_good_call()139 void templ_good_call() {
140   templ<Base, Derived>(); // OK, upcast to a public base
141 }
142