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