// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-static-cast-downcast %t class Base { }; class Derived : public Base { }; class Base2 { }; class MultiDerived : public Base, public Base2 { }; class PolymorphicBase { public: virtual ~PolymorphicBase(); }; class PolymorphicDerived : public PolymorphicBase { }; class PolymorphicMultiDerived : public Base, public PolymorphicBase { }; void pointers() { auto P0 = static_cast(new Base()); // 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] const Base* B0; auto PC0 = static_cast(B0); // 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] auto P1 = static_cast(new Derived()); // OK, upcast to a public base auto P2 = static_cast(new MultiDerived()); // OK, upcast to a public base auto P3 = static_cast(new MultiDerived()); // OK, upcast to a public base } void pointers_polymorphic() { auto PP0 = static_cast(new PolymorphicBase()); // 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] // CHECK-FIXES: auto PP0 = dynamic_cast(new PolymorphicBase()); const PolymorphicBase* B0; auto PPC0 = static_cast(B0); // 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] // CHECK-FIXES: auto PPC0 = dynamic_cast(B0); auto B1 = static_cast(new PolymorphicDerived()); // OK, upcast to a public base auto B2 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base auto B3 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base } void arrays() { Base ArrayOfBase[10]; auto A0 = static_cast(ArrayOfBase); // 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] } void arrays_polymorphic() { PolymorphicBase ArrayOfPolymorphicBase[10]; auto AP0 = static_cast(ArrayOfPolymorphicBase); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead // CHECK-FIXES: auto AP0 = dynamic_cast(ArrayOfPolymorphicBase); } void references() { Base B0; auto R0 = static_cast(B0); // 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] Base& RefToBase = B0; auto R1 = static_cast(RefToBase); // 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] const Base& ConstRefToBase = B0; auto RC1 = static_cast(ConstRefToBase); // 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] Derived RD1; auto R2 = static_cast(RD1); // OK, upcast to a public base } void references_polymorphic() { PolymorphicBase B0; auto RP0 = static_cast(B0); // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead // CHECK-FIXES: auto RP0 = dynamic_cast(B0); PolymorphicBase& RefToPolymorphicBase = B0; auto RP1 = static_cast(RefToPolymorphicBase); // 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] // CHECK-FIXES: auto RP1 = dynamic_cast(RefToPolymorphicBase); const PolymorphicBase& ConstRefToPolymorphicBase = B0; auto RPC2 = static_cast(ConstRefToPolymorphicBase); // 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] // CHECK-FIXES: auto RPC2 = dynamic_cast(ConstRefToPolymorphicBase); PolymorphicDerived d1; auto RP2 = static_cast(d1); // OK, upcast to a public base } template void templ() { auto B0 = static_cast(new D()); } void templ_bad_call() { templ(); //FIXME: this should trigger a warning } void templ_good_call() { templ(); // OK, upcast to a public base }