xref: /llvm-project/clang/test/Analysis/osobjectcstylecastchecker_test.cpp (revision 90377308de6cac8239bc1a1dcd32b57b9ec91444)
1 // RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.osx.OSObjectCStyleCast %s -verify
2 #include "os_object_base.h"
3 
4 struct OSArray : public OSObject {
5   unsigned getCount();
6 };
7 
8 struct A {
9   int x;
10 };
11 struct B : public A {
12   unsigned getCount();
13 };
14 
warn_on_explicit_downcast(OSObject * obj)15 unsigned warn_on_explicit_downcast(OSObject * obj) {
16   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}}
17   return a->getCount();
18 }
19 
no_warn_on_upcast(OSArray * arr)20 void no_warn_on_upcast(OSArray *arr) {
21   OSObject *obj = (OSObject *) arr;
22   obj->retain();
23   obj->release();
24 }
25 
no_warn_on_dynamic_cast(OSObject * obj)26 unsigned no_warn_on_dynamic_cast(OSObject *obj) {
27   OSArray *a = OSDynamicCast(OSArray, obj);
28   return a->getCount();
29 }
30 
no_warn_on_primitive_conversion(OSArray * arr)31 __SIZE_TYPE__ no_warn_on_primitive_conversion(OSArray *arr) {
32   return (__SIZE_TYPE__) arr;
33 }
34 
no_warn_on_other_type_cast(A * a)35 unsigned no_warn_on_other_type_cast(A *a) {
36   B *b = (B *) a;
37   return b->getCount();
38 }
39 
no_warn_alloc_class_with_name()40 unsigned no_warn_alloc_class_with_name() {
41   OSArray *a = (OSArray *)OSMetaClass::allocClassWithName("OSArray"); // no warning
42   return a->getCount();
43 }
44 
warn_alloc_class_with_name()45 unsigned warn_alloc_class_with_name() {
46   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   return a->getCount();
48 }
49