xref: /llvm-project/clang/test/Analysis/osobjectcstylecastchecker_test.cpp (revision 90377308de6cac8239bc1a1dcd32b57b9ec91444)
1b0914e72SArtem Dergachev // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.osx.OSObjectCStyleCast %s -verify
22add627eSGeorge Karpenkov #include "os_object_base.h"
32add627eSGeorge Karpenkov 
42add627eSGeorge Karpenkov struct OSArray : public OSObject {
52add627eSGeorge Karpenkov   unsigned getCount();
62add627eSGeorge Karpenkov };
72add627eSGeorge Karpenkov 
82add627eSGeorge Karpenkov struct A {
92add627eSGeorge Karpenkov   int x;
102add627eSGeorge Karpenkov };
112add627eSGeorge Karpenkov struct B : public A {
122add627eSGeorge Karpenkov   unsigned getCount();
132add627eSGeorge Karpenkov };
142add627eSGeorge Karpenkov 
warn_on_explicit_downcast(OSObject * obj)152add627eSGeorge Karpenkov unsigned warn_on_explicit_downcast(OSObject * obj) {
168c5ca7c6SArtem Dergachev   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}}
172add627eSGeorge Karpenkov   return a->getCount();
182add627eSGeorge Karpenkov }
192add627eSGeorge Karpenkov 
no_warn_on_upcast(OSArray * arr)202add627eSGeorge Karpenkov void no_warn_on_upcast(OSArray *arr) {
212add627eSGeorge Karpenkov   OSObject *obj = (OSObject *) arr;
222add627eSGeorge Karpenkov   obj->retain();
232add627eSGeorge Karpenkov   obj->release();
242add627eSGeorge Karpenkov }
252add627eSGeorge Karpenkov 
no_warn_on_dynamic_cast(OSObject * obj)262add627eSGeorge Karpenkov unsigned no_warn_on_dynamic_cast(OSObject *obj) {
272add627eSGeorge Karpenkov   OSArray *a = OSDynamicCast(OSArray, obj);
282add627eSGeorge Karpenkov   return a->getCount();
292add627eSGeorge Karpenkov }
302add627eSGeorge Karpenkov 
no_warn_on_primitive_conversion(OSArray * arr)314b96530fSReid Kleckner __SIZE_TYPE__ no_warn_on_primitive_conversion(OSArray *arr) {
324b96530fSReid Kleckner   return (__SIZE_TYPE__) arr;
332add627eSGeorge Karpenkov }
342add627eSGeorge Karpenkov 
no_warn_on_other_type_cast(A * a)352add627eSGeorge Karpenkov unsigned no_warn_on_other_type_cast(A *a) {
362add627eSGeorge Karpenkov   B *b = (B *) a;
372add627eSGeorge Karpenkov   return b->getCount();
382add627eSGeorge Karpenkov }
392add627eSGeorge Karpenkov 
no_warn_alloc_class_with_name()40*90377308SValeriy Savchenko unsigned no_warn_alloc_class_with_name() {
41*90377308SValeriy Savchenko   OSArray *a = (OSArray *)OSMetaClass::allocClassWithName("OSArray"); // no warning
42*90377308SValeriy Savchenko   return a->getCount();
43*90377308SValeriy Savchenko }
44*90377308SValeriy Savchenko 
warn_alloc_class_with_name()45*90377308SValeriy Savchenko unsigned warn_alloc_class_with_name() {
46*90377308SValeriy Savchenko   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}}
47*90377308SValeriy Savchenko   return a->getCount();
48*90377308SValeriy Savchenko }
49