1 | // RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-cstyle-cast %t |
2 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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> |
131 | void templ() { |
132 | auto B0 = (B*)new D(); |
133 | } |
134 | |
135 | void templ_bad_call() { |
136 | templ<Derived, Base>(); //FIXME: this should trigger a warning |
137 | } |
138 | |
139 | void templ_good_call() { |
140 | templ<Base, Derived>(); // OK, upcast to a public base |
141 | } |
142 | |