192 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s2 3#include "InlineObjCInstanceMethod.h"4 5@interface MyParent : NSObject6- (int)getZero;7@end8@implementation MyParent9- (int)getZero {10 return 0;11}12@end13 14@interface PublicClass () {15 int value2;16}17@property (readwrite) int value1;18- (void)setValue2:(int)newValue2;19@end20 21@implementation PublicClass22 23- (int)getZeroPublic {24 return 0;25}26 27@synthesize value1;28 29- (int)value2 {30 return value2;31} 32- (void)setValue2:(int)newValue {33 value2 = newValue;34}35 36- (int)value3 {37 return value3;38} 39- (void)setValue3:(int)newValue {40 value3 = newValue;41}42 43@end44 45@interface MyClassWithPublicParent : PublicClass46- (int)getZeroPublic;47@end48@implementation MyClassWithPublicParent49- (int)getZeroPublic {50 return 0;51}52@end53 54// Category overrides a public method.55@interface PublicSubClass (PrvateCat)56 - (int) getZeroPublic;57@end58@implementation PublicSubClass (PrvateCat)59- (int)getZeroPublic {60 return 0;61}62@end63 64 65@interface MyClass : MyParent {66 int value;67}68- (int)getZero;69@property int value;70@end71 72// Since class is private, we assume that it cannot be subclassed.73// False negative: this class is "privately subclassed". this is very rare 74// in practice.75@implementation MyClass76+ (int) testTypeFromParam:(MyParent*) p {77 int m = 0;78 int z = [p getZero];79 if (z)80 return 5/m; // false negative81 return 5/[p getZero];// expected-warning {{Division by zero}}82}83 84// Here only one definition is possible, since the declaration is not visible 85// from outside. 86+ (int) testTypeFromParamPrivateChild:(MyClass*) c {87 int m = 0;88 int z = [c getZero]; // MyClass overrides getZero to return '1'.89 if (z)90 return 5/m; // expected-warning {{Division by zero}}91 return 5/[c getZero];//no warning92}93 94- (int)getZero {95 return 1;96}97 98- (int)value {99 return value;100}101 102- (void)setValue:(int)newValue {103 value = newValue;104}105 106// Test ivar access.107- (int) testIvarInSelf {108 value = 0;109 return 5/value; // expected-warning {{Division by zero}}110}111 112+ (int) testIvar: (MyClass*) p {113 p.value = 0;114 return 5/p.value; // expected-warning {{Division by zero}}115}116 117// Test simple property access.118+ (int) testProperty: (MyClass*) p {119 int x= 0;120 [p setValue:0];121 return 5/[p value]; // expected-warning {{Division by zero}} 122}123 124@end125 126// The class is prvate and is not subclassed.127int testCallToPublicAPIInParent(MyClassWithPublicParent *p) {128 int m = 0;129 int z = [p getZeroPublic];130 if (z)131 return 5/m; // no warning132 return 5/[p getZeroPublic];// expected-warning {{Division by zero}} 133}134 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*).141int testCallToPublicAPI(PublicClass *p) {142 int m = 0;143 int z = [p getZeroPublic];144 if (z)145 return 5/m; // expected-warning {{Division by zero}}146 return 5/[p getZeroPublic];// expected-warning {{Division by zero}} 147}148 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.151int testCallToPublicAPICat(PublicSubClass *p) {152 int m = 0;153 int z = [p getZeroPublic];154 if (z)155 return 5/m; // expected-warning {{Division by zero}}156 return 5/[p getZeroPublic];// expected-warning {{Division by zero}} 157}158 159// Test public property - properties should always be inlined, regardless 160// weither they are "public" or private. 161int testPublicProperty(PublicClass *p) {162 int x = 0;163 p.value3 = 0;164 if (p.value3 != 0)165 return 5/x; 166 return 5/p.value3;// expected-warning {{Division by zero}}167}168 169int testExtension(PublicClass *p) {170 int x = 0;171 [p setValue2:0];172 if ([p value2] != 0)173 return 5/x; // expected-warning {{Division by zero}}174 return 5/[p value2]; // expected-warning {{Division by zero}}175}176 177// TODO: we do not handle synthesized properties yet.178int testPropertySynthesized(PublicClass *p) {179 [p setValue1:0];180 return 5/[p value1]; 181}182 183// Test definition not available edge case.184@interface DefNotAvailClass : NSObject // expected-note {{receiver is instance of class declared here}}185@end186id testDefNotAvailableInlined(DefNotAvailClass *C) {187 return [C mem]; // expected-warning {{instance method '-mem' not found}}188}189id testDefNotAvailable(DefNotAvailClass *C) {190 return testDefNotAvailableInlined(C);191}192