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

source code of clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-static-cast-downcast.cpp