| // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.osx.OSObjectCStyleCast %s -verify |
| #include "os_object_base.h" |
| |
| struct OSArray : public OSObject { |
| unsigned getCount(); |
| }; |
| |
| struct A { |
| int x; |
| }; |
| struct B : public A { |
| unsigned getCount(); |
| }; |
| |
| unsigned warn_on_explicit_downcast(OSObject * obj) { |
| OSArray *a = (OSArray *) obj; // expected-warning{{C-style cast of an OSObject is prone to type confusion attacks; use 'OSRequiredCast' if the object is definitely of type 'OSArray', or 'OSDynamicCast' followed by a null check if unsure}} |
| return a->getCount(); |
| } |
| |
| void no_warn_on_upcast(OSArray *arr) { |
| OSObject *obj = (OSObject *) arr; |
| obj->retain(); |
| obj->release(); |
| } |
| |
| unsigned no_warn_on_dynamic_cast(OSObject *obj) { |
| OSArray *a = OSDynamicCast(OSArray, obj); |
| return a->getCount(); |
| } |
| |
| __SIZE_TYPE__ no_warn_on_primitive_conversion(OSArray *arr) { |
| return (__SIZE_TYPE__) arr; |
| } |
| |
| unsigned no_warn_on_other_type_cast(A *a) { |
| B *b = (B *) a; |
| return b->getCount(); |
| } |
| |
| unsigned no_warn_alloc_class_with_name() { |
| OSArray *a = (OSArray *)OSMetaClass::allocClassWithName("OSArray"); // no warning |
| return a->getCount(); |
| } |
| |
| unsigned warn_alloc_class_with_name() { |
| OSArray *a = (OSArray *)OSMetaClass::allocClassWithName("OSObject"); // expected-warning{{C-style cast of an OSObject is prone to type confusion attacks; use 'OSRequiredCast' if the object is definitely of type 'OSArray', or 'OSDynamicCast' followed by a null check if unsure}} |
| return a->getCount(); |
| } |