1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s
3 #include "InlineObjCInstanceMethod.h"
5 @interface MyParent : NSObject
8 @implementation MyParent
14 @interface PublicClass () {
17 @property (readwrite) int value1;
18 - (void)setValue2:(int)newValue2;
21 @implementation PublicClass
23 - (int)getZeroPublic {
32 - (void)setValue2:(int)newValue {
39 - (void)setValue3:(int)newValue {
45 @interface MyClassWithPublicParent : PublicClass
48 @implementation MyClassWithPublicParent
49 - (int)getZeroPublic {
54 // Category overrides a public method.
55 @interface PublicSubClass (PrvateCat)
56 - (int) getZeroPublic;
58 @implementation PublicSubClass (PrvateCat)
59 - (int)getZeroPublic {
65 @interface MyClass : MyParent {
72 // Since class is private, we assume that it cannot be subclassed.
73 // False negative: this class is "privately subclassed". this is very rare
75 @implementation MyClass
76 + (int) testTypeFromParam:(MyParent*) p {
80 return 5/m; // false negative
81 return 5/[p getZero];// expected-warning {{Division by zero}}
84 // Here only one definition is possible, since the declaration is not visible
86 + (int) testTypeFromParamPrivateChild:(MyClass*) c {
88 int z = [c getZero]; // MyClass overrides getZero to return '1'.
90 return 5/m; // expected-warning {{Division by zero}}
91 return 5/[c getZero];//no warning
102 - (void)setValue:(int)newValue {
107 - (int) testIvarInSelf {
109 return 5/value; // expected-warning {{Division by zero}}
112 + (int) testIvar: (MyClass*) p {
114 return 5/p.value; // expected-warning {{Division by zero}}
117 // Test simple property access.
118 + (int) testProperty: (MyClass*) p {
121 return 5/[p value]; // expected-warning {{Division by zero}}
126 // The class is prvate and is not subclassed.
127 int testCallToPublicAPIInParent(MyClassWithPublicParent *p) {
129 int z = [p getZeroPublic];
131 return 5/m; // no warning
132 return 5/[p getZeroPublic];// expected-warning {{Division by zero}}
135 // When the called method is public (due to it being defined outside of main file),
136 // split the path and analyze both branches.
137 // In this case, p can be either the object of type MyParent* or MyClass*:
138 // - If it's MyParent*, getZero returns 0.
139 // - If it's MyClass*, getZero returns 1 and 'return 5/m' is reachable.
140 // Declaration is provate, but p can be a subclass (MyClass*).
141 int testCallToPublicAPI(PublicClass *p) {
143 int z = [p getZeroPublic];
145 return 5/m; // expected-warning {{Division by zero}}
146 return 5/[p getZeroPublic];// expected-warning {{Division by zero}}
149 // Even though the method is privately declared in the category, the parent
150 // declares the method as public. Assume the instance can be subclassed.
151 int testCallToPublicAPICat(PublicSubClass *p) {
153 int z = [p getZeroPublic];
155 return 5/m; // expected-warning {{Division by zero}}
156 return 5/[p getZeroPublic];// expected-warning {{Division by zero}}
159 // Test public property - properties should always be inlined, regardless
160 // weither they are "public" or private.
161 int testPublicProperty(PublicClass *p) {
166 return 5/p.value3;// expected-warning {{Division by zero}}
169 int testExtension(PublicClass *p) {
173 return 5/x; // expected-warning {{Division by zero}}
174 return 5/[p value2]; // expected-warning {{Division by zero}}
177 // TODO: we do not handle synthesized properties yet.
178 int testPropertySynthesized(PublicClass *p) {
183 // Test definition not available edge case.
184 @interface DefNotAvailClass : NSObject // expected-note {{receiver is instance of class declared here}}
186 id testDefNotAvailableInlined(DefNotAvailClass *C) {
187 return [C mem]; // expected-warning {{instance method '-mem' not found}}
189 id testDefNotAvailable(DefNotAvailClass *C) {
190 return testDefNotAvailableInlined(C);