1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s
#include "InlineObjCInstanceMethod.h"
@interface MyParent : NSObject
- (int)getZero;
@end
@implementation MyParent
- (int)getZero {
return 0;
}
@end
@interface PublicClass () {
int value2;
}
@property (readwrite) int value1;
- (void)setValue2:(int)newValue2;
@end
@implementation PublicClass
- (int)getZeroPublic {
return 0;
}
@synthesize value1;
- (int)value2 {
return value2;
}
- (void)setValue2:(int)newValue {
value2 = newValue;
}
- (int)value3 {
return value3;
}
- (void)setValue3:(int)newValue {
value3 = newValue;
}
@end
@interface MyClassWithPublicParent : PublicClass
- (int)getZeroPublic;
@end
@implementation MyClassWithPublicParent
- (int)getZeroPublic {
return 0;
}
@end
// Category overrides a public method.
@interface PublicSubClass (PrvateCat)
- (int) getZeroPublic;
@end
@implementation PublicSubClass (PrvateCat)
- (int)getZeroPublic {
return 0;
}
@end
@interface MyClass : MyParent {
int value;
}
- (int)getZero;
@property int value;
@end
// Since class is private, we assume that it cannot be subclassed.
// False negative: this class is "privately subclassed". this is very rare
// in practice.
@implementation MyClass
+ (int) testTypeFromParam:(MyParent*) p {
int m = 0;
int z = [p getZero];
if (z)
return 5/m; // false negative
return 5/[p getZero];// expected-warning {{Division by zero}}
}
// Here only one definition is possible, since the declaration is not visible
// from outside.
+ (int) testTypeFromParamPrivateChild:(MyClass*) c {
int m = 0;
int z = [c getZero]; // MyClass overrides getZero to return '1'.
if (z)
return 5/m; // expected-warning {{Division by zero}}
return 5/[c getZero];//no warning
}
- (int)getZero {
return 1;
}
- (int)value {
return value;
}
- (void)setValue:(int)newValue {
value = newValue;
}
// Test ivar access.
- (int) testIvarInSelf {
value = 0;
return 5/value; // expected-warning {{Division by zero}}
}
+ (int) testIvar: (MyClass*) p {
p.value = 0;
return 5/p.value; // expected-warning {{Division by zero}}
}
// Test simple property access.
+ (int) testProperty: (MyClass*) p {
int x= 0;
[p setValue:0];
return 5/[p value]; // expected-warning {{Division by zero}}
}
@end
// The class is prvate and is not subclassed.
int testCallToPublicAPIInParent(MyClassWithPublicParent *p) {
int m = 0;
int z = [p getZeroPublic];
if (z)
return 5/m; // no warning
return 5/[p getZeroPublic];// expected-warning {{Division by zero}}
}
// When the called method is public (due to it being defined outside of main file),
// split the path and analyze both branches.
// In this case, p can be either the object of type MyParent* or MyClass*:
// - If it's MyParent*, getZero returns 0.
// - If it's MyClass*, getZero returns 1 and 'return 5/m' is reachable.
// Declaration is provate, but p can be a subclass (MyClass*).
int testCallToPublicAPI(PublicClass *p) {
int m = 0;
int z = [p getZeroPublic];
if (z)
return 5/m; // expected-warning {{Division by zero}}
return 5/[p getZeroPublic];// expected-warning {{Division by zero}}
}
// Even though the method is privately declared in the category, the parent
// declares the method as public. Assume the instance can be subclassed.
int testCallToPublicAPICat(PublicSubClass *p) {
int m = 0;
int z = [p getZeroPublic];
if (z)
return 5/m; // expected-warning {{Division by zero}}
return 5/[p getZeroPublic];// expected-warning {{Division by zero}}
}
// Test public property - properties should always be inlined, regardless
// weither they are "public" or private.
int testPublicProperty(PublicClass *p) {
int x = 0;
p.value3 = 0;
if (p.value3 != 0)
return 5/x;
return 5/p.value3;// expected-warning {{Division by zero}}
}
int testExtension(PublicClass *p) {
int x = 0;
[p setValue2:0];
if ([p value2] != 0)
return 5/x; // expected-warning {{Division by zero}}
return 5/[p value2]; // expected-warning {{Division by zero}}
}
// TODO: we do not handle synthesized properties yet.
int testPropertySynthesized(PublicClass *p) {
[p setValue1:0];
return 5/[p value1];
}
// Test definition not available edge case.
@interface DefNotAvailClass : NSObject // expected-note {{receiver is instance of class declared here}}
@end
id testDefNotAvailableInlined(DefNotAvailClass *C) {
return [C mem]; // expected-warning {{instance method '-mem' not found}}
}
id testDefNotAvailable(DefNotAvailClass *C) {
return testDefNotAvailableInlined(C);
}
|