brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.2 KiB · 62c945c Raw
267 lines · cpp
1// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.MemoryUnsafeCastChecker -verify %s2 3class Base { };4class Derived : public Base { };5 6template<typename Target, typename Source>7Target& downcast_ref(Source& source){8  [[clang::suppress]]9  return static_cast<Target&>(source);10}11 12template<typename Target, typename Source>13Target* downcast_ptr(Source* source){14  [[clang::suppress]]15  return static_cast<Target*>(source);16}17 18void test_pointers(Base *base) {19  Derived *derived_static = static_cast<Derived*>(base);20  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}21  Derived *derived_reinterpret = reinterpret_cast<Derived*>(base);22  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}23  Derived *derived_c = (Derived*)base;24  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}25  Derived *derived_d = downcast_ptr<Derived, Base>(base);  // no warning26}27 28void test_non_pointers(Derived derived) {29  Base base_static = static_cast<Base>(derived);  // no warning30}31 32void test_refs(Base &base) {33  Derived &derived_static = static_cast<Derived&>(base);34  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}35  Derived &derived_reinterpret = reinterpret_cast<Derived&>(base);36  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}37  Derived &derived_c = (Derived&)base;38  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}39  Derived &derived_d = downcast_ref<Derived, Base>(base);  // no warning40}41 42class BaseVirtual {43  virtual void virtual_base_function();44};45 46class DerivedVirtual : public BaseVirtual {47  void virtual_base_function() override { }48};49 50void test_dynamic_casts(BaseVirtual *base_ptr, BaseVirtual &base_ref) {51  DerivedVirtual *derived_dynamic_ptr = dynamic_cast<DerivedVirtual*>(base_ptr);52  // expected-warning@-1{{Unsafe cast from base type 'BaseVirtual' to derived type 'DerivedVirtual'}}53  DerivedVirtual &derived_dynamic_ref = dynamic_cast<DerivedVirtual&>(base_ref);54  // expected-warning@-1{{Unsafe cast from base type 'BaseVirtual' to derived type 'DerivedVirtual'}}55}56 57struct BaseStruct { };58struct DerivedStruct : BaseStruct { };59 60void test_struct_pointers(struct BaseStruct *base_struct) {61  struct DerivedStruct *derived_static = static_cast<struct DerivedStruct*>(base_struct);62  // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}63  struct DerivedStruct *derived_reinterpret = reinterpret_cast<struct DerivedStruct*>(base_struct);64  // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}65  struct DerivedStruct *derived_c = (struct DerivedStruct*)base_struct;66  // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}67}68 69typedef struct BaseStruct BStruct;70typedef struct DerivedStruct DStruct;71 72void test_struct_refs(BStruct &base_struct) {73  DStruct &derived_static = static_cast<DStruct&>(base_struct);74  // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}75  DStruct &derived_reinterpret = reinterpret_cast<DStruct&>(base_struct);76  // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}77  DStruct &derived_c = (DStruct&)base_struct;78  // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}79}80 81int counter = 0;82void test_recursive(BStruct &base_struct) {83  if (counter == 5)84    return;85  counter++;86  DStruct &derived_static = static_cast<DStruct&>(base_struct);87  // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}}88}89 90template<typename T>91class BaseTemplate { };92 93template<typename T>94class DerivedTemplate : public BaseTemplate<T> { };95 96void test_templates(BaseTemplate<int> *base, BaseTemplate<int> &base_ref) {97  DerivedTemplate<int> *derived_static = static_cast<DerivedTemplate<int>*>(base);98  // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}99  DerivedTemplate<int> *derived_reinterpret = reinterpret_cast<DerivedTemplate<int>*>(base);100  // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}101  DerivedTemplate<int> *derived_c = (DerivedTemplate<int>*)base;102  // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}103  DerivedTemplate<int> &derived_static_ref = static_cast<DerivedTemplate<int>&>(base_ref);104  // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}105  DerivedTemplate<int> &derived_reinterpret_ref = reinterpret_cast<DerivedTemplate<int>&>(base_ref);106  // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}107  DerivedTemplate<int> &derived_c_ref = (DerivedTemplate<int>&)base_ref;108  // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}}109}110 111#define CAST_MACRO_STATIC(X,Y) (static_cast<Y>(X))112#define CAST_MACRO_REINTERPRET(X,Y) (reinterpret_cast<Y>(X))113#define CAST_MACRO_C(X,Y) ((Y)X)114 115void test_macro_static(Base *base, Derived *derived, Base &base_ref) {116  Derived *derived_static = CAST_MACRO_STATIC(base, Derived*);117  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}118  Derived &derived_static_ref = CAST_MACRO_STATIC(base_ref, Derived&);119  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}120  Base *base_static_same = CAST_MACRO_STATIC(base, Base*);  // no warning121  Base *base_static_upcast = CAST_MACRO_STATIC(derived, Base*);  // no warning122}123 124void test_macro_reinterpret(Base *base, Derived *derived, Base &base_ref) {125  Derived *derived_reinterpret = CAST_MACRO_REINTERPRET(base, Derived*);126  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}127  Derived &derived_reinterpret_ref = CAST_MACRO_REINTERPRET(base_ref, Derived&);128  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}129  Base *base_reinterpret_same = CAST_MACRO_REINTERPRET(base, Base*);  // no warning130  Base *base_reinterpret_upcast = CAST_MACRO_REINTERPRET(derived, Base*);  // no warning131}132 133void test_macro_c(Base *base, Derived *derived, Base &base_ref) {134  Derived *derived_c = CAST_MACRO_C(base, Derived*);135  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}136  Derived &derived_c_ref = CAST_MACRO_C(base_ref, Derived&);137  // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}}138  Base *base_c_same = CAST_MACRO_C(base, Base*);  // no warning139  Base *base_c_upcast = CAST_MACRO_C(derived, Base*);  // no warning140}141 142struct BaseStructCpp {143  int t;144  void increment() { t++; }145};146struct DerivedStructCpp : BaseStructCpp {147  void increment_t() {increment();}148};149 150void test_struct_cpp_pointers(struct BaseStructCpp *base_struct) {151  struct DerivedStructCpp *derived_static = static_cast<struct DerivedStructCpp*>(base_struct);152  // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}153  struct DerivedStructCpp *derived_reinterpret = reinterpret_cast<struct DerivedStructCpp*>(base_struct);154  // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}155  struct DerivedStructCpp *derived_c = (struct DerivedStructCpp*)base_struct;156  // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}157}158 159typedef struct BaseStructCpp BStructCpp;160typedef struct DerivedStructCpp DStructCpp;161 162void test_struct_cpp_refs(BStructCpp &base_struct, DStructCpp &derived_struct) {163  DStructCpp &derived_static = static_cast<DStructCpp&>(base_struct);164  // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}165  DStructCpp &derived_reinterpret = reinterpret_cast<DStructCpp&>(base_struct);166  // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}167  DStructCpp &derived_c = (DStructCpp&)base_struct;168  // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}}169  BStructCpp &base = (BStructCpp&)derived_struct; // no warning170  BStructCpp &base_static = static_cast<BStructCpp&>(derived_struct); // no warning171  BStructCpp &base_reinterpret = reinterpret_cast<BStructCpp&>(derived_struct); // no warning172}173 174struct stack_st { };175 176#define STACK_OF(type) struct stack_st_##type177 178void test_stack(stack_st *base) {179  STACK_OF(void) *derived = (STACK_OF(void)*)base;180  // expected-warning@-1{{Unsafe cast from type 'stack_st' to an unrelated type 'stack_st_void'}}181}182 183class Parent { };184class Child1 : public Parent { };185class Child2 : public Parent { };186 187void test_common_parent(Child1 *c1, Child2 *c2) {188  Child2 *c2_cstyle = (Child2 *)c1;189  // expected-warning@-1{{Unsafe cast from type 'Child1' to an unrelated type 'Child2'}}190  Child2 *c2_reinterpret = reinterpret_cast<Child2 *>(c1);191  // expected-warning@-1{{Unsafe cast from type 'Child1' to an unrelated type 'Child2'}}192}193 194class Type1 { };195class Type2 { };196 197void test_unrelated_ref(Type1 &t1, Type2 &t2) {198  Type2 &t2_cstyle = (Type2 &)t1;199  // expected-warning@-1{{Unsafe cast from type 'Type1' to an unrelated type 'Type2'}}200  Type2 &t2_reinterpret = reinterpret_cast<Type2 &>(t1);201  // expected-warning@-1{{Unsafe cast from type 'Type1' to an unrelated type 'Type2'}}202  Type2 &t2_same = reinterpret_cast<Type2 &>(t2); // no warning203}204 205 206class VirtualClass1 {207  virtual void virtual_base_function();208};209 210class VirtualClass2 {211  void virtual_base_function();212};213 214void test_unrelated_virtual(VirtualClass1 &v1) {215  VirtualClass2 &v2 = dynamic_cast<VirtualClass2 &>(v1);216  // expected-warning@-1{{Unsafe cast from type 'VirtualClass1' to an unrelated type 'VirtualClass2'}}217}218 219struct StructA { };220struct StructB { };221 222typedef struct StructA StA;223typedef struct StructB StB;224 225void test_struct_unrelated_refs(StA &a, StB &b) {226  StB &b_reinterpret = reinterpret_cast<StB&>(a);227  // expected-warning@-1{{Unsafe cast from type 'StructA' to an unrelated type 'StructB'}}228  StB &b_c = (StB&)a;229  // expected-warning@-1{{Unsafe cast from type 'StructA' to an unrelated type 'StructB'}}230  StA &a_local = (StA&)b;231  // expected-warning@-1{{Unsafe cast from type 'StructB' to an unrelated type 'StructA'}}232  StA &a_reinterpret = reinterpret_cast<StA&>(b);233  // expected-warning@-1{{Unsafe cast from type 'StructB' to an unrelated type 'StructA'}}234  StA &a_same = (StA&)a; // no warning235}236 237template<typename T>238class DeferrableRefCounted {239public:240  void deref() const {241    auto this_to_T =  static_cast<const T*>(this); // no warning242  }243};244 245class SomeArrayClass : public DeferrableRefCounted<SomeArrayClass> { };246 247void test_this_to_template(SomeArrayClass *ptr) {248  ptr->deref();249};250 251template<typename WeakPtrFactoryType>252class CanMakeWeakPtrBase {253public:254  void initializeWeakPtrFactory() const {255    auto &this_to_T = static_cast<const WeakPtrFactoryType&>(*this);256  }257};258 259template<typename T>260using CanMakeWeakPtr = CanMakeWeakPtrBase<T>;261 262class EventLoop : public CanMakeWeakPtr<EventLoop> { };263 264void test_this_to_template_ref(EventLoop *ptr) {265  ptr->initializeWeakPtrFactory();266};267