1 // RUN: %clang_cc1 -verify -Wno-deprecated-declarations -Wno-objc-root-class %s 2 3 @interface Unrelated 4 @end 5 6 @interface NSObject 7 + (id)new; 8 + (id)alloc; 9 - (NSObject *)init; 10 11 - (id)retain; // expected-note{{instance method 'retain' is assumed to return an instance of its receiver type ('NSArray *')}} 12 - autorelease; 13 14 - (id)self; 15 16 - (id)copy; 17 - (id)mutableCopy; 18 19 // Do not infer when instance/class mismatches 20 - (id)newNotInferred; 21 - (id)alloc; 22 + (id)initWithBlarg; 23 + (id)self; 24 25 // Do not infer when the return types mismatch. 26 - (Unrelated *)initAsUnrelated; 27 @end 28 29 @interface NSString : NSObject 30 - (id)init; 31 - (id)initWithCString:(const char*)string; 32 @end 33 34 @interface NSArray : NSObject 35 - (unsigned)count; 36 @end 37 38 @interface NSBlah 39 @end 40 41 @interface NSMutableArray : NSArray 42 @end 43 44 @interface NSBlah () 45 + (Unrelated *)newUnrelated; 46 @end 47 48 void test_inference() { 49 // Inference based on method family 50 __typeof__(([[NSString alloc] init])) *str = (NSString**)0; 51 __typeof__(([[[[NSString new] self] retain] autorelease])) *str2 = (NSString **)0; 52 __typeof__(([[NSString alloc] initWithCString:"blah"])) *str3 = (NSString**)0; 53 54 // Not inferred 55 __typeof__(([[NSString new] copy])) *id1 = (id*)0; 56 57 // Not inferred due to instance/class mismatches 58 __typeof__(([[NSString new] newNotInferred])) *id2 = (id*)0; 59 __typeof__(([[NSString new] alloc])) *id3 = (id*)0; 60 __typeof__(([NSString self])) *id4 = (id*)0; 61 __typeof__(([NSString initWithBlarg])) *id5 = (id*)0; 62 63 // Not inferred due to return type mismatch 64 __typeof__(([[NSString alloc] initAsUnrelated])) *unrelated = (Unrelated**)0; 65 __typeof__(([NSBlah newUnrelated])) *unrelated2 = (Unrelated**)0; 66 67 68 NSArray *arr = [[NSMutableArray alloc] init]; 69 NSMutableArray *marr = [arr retain]; // expected-warning{{incompatible pointer types initializing 'NSMutableArray *' with an expression of type 'NSArray *'}} 70 } 71 72 @implementation NSBlah 73 + (Unrelated *)newUnrelated { 74 return (Unrelated *)0; 75 } 76 @end 77 78 @implementation NSBlah (Cat) 79 + (Unrelated *)newUnrelated2 { 80 return (Unrelated *)0; 81 } 82 @end 83 84 @interface A 85 - (id)initBlah; // expected-note 2{{overridden method is part of the 'init' method family}} 86 @end 87 88 @interface B : A 89 - (Unrelated *)initBlah; // expected-warning{{method is expected to return an instance of its class type 'B', but is declared to return 'Unrelated *'}} 90 @end 91 92 @interface C : A 93 @end 94 95 @implementation C 96 - (Unrelated *)initBlah { // expected-warning{{method is expected to return an instance of its class type 'C', but is declared to return 'Unrelated *'}} 97 return (Unrelated *)0; 98 } 99 @end 100 101 @interface D 102 + (id)newBlarg; // expected-note{{overridden method is part of the 'new' method family}} 103 @end 104 105 @interface D () 106 + alloc; // expected-note{{overridden method is part of the 'alloc' method family}} 107 @end 108 109 @implementation D 110 + (Unrelated *)newBlarg { // expected-warning{{method is expected to return an instance of its class type 'D', but is declared to return 'Unrelated *'}} 111 return (Unrelated *)0; 112 } 113 114 + (Unrelated *)alloc { // expected-warning{{method is expected to return an instance of its class type 'D', but is declared to return 'Unrelated *'}} 115 return (Unrelated *)0; 116 } 117 @end 118 119 @protocol P1 120 - (id)initBlah; // expected-note{{overridden method is part of the 'init' method family}} 121 - (int)initBlarg; 122 @end 123 124 @protocol P2 <P1> 125 - (int)initBlah; // expected-warning{{protocol method is expected to return an instance of the implementing class, but is declared to return 'int'}} 126 - (int)initBlarg; 127 - (int)initBlech; 128 @end 129 130 @interface E 131 - init; 132 @end 133 134 @implementation E 135 - init { 136 return self; 137 } 138 @end 139 140 @protocol P3 141 + (NSString *)newString; 142 @end 143 144 @interface F<P3> 145 @end 146 147 @implementation F 148 + (NSString *)newString { return @"blah"; } 149 @end 150 151 // <rdar://problem/9340699> 152 @interface G 153 - (id)_ABC_init __attribute__((objc_method_family(init))); // expected-note {{method '_ABC_init' declared here}} 154 @end 155 156 @interface G (Additions) 157 - (id)_ABC_init2 __attribute__((objc_method_family(init))); 158 @end 159 160 @implementation G (Additions) 161 - (id)_ABC_init { // expected-warning {{category is implementing a method which will also be implemented by its primary class}} 162 return 0; 163 } 164 - (id)_ABC_init2 { 165 return 0; 166 } 167 - (id)_ABC_init3 { 168 return 0; 169 } 170 @end 171 172 // PR12384 173 @interface Fail @end 174 @protocol X @end 175 @implementation Fail 176 - (id<X>) initWithX // expected-note {{compiler has implicitly changed method 'initWithX' return type}} 177 { 178 return (id)self; // expected-warning {{casting 'Fail *' to incompatible type 'id<X>'}} 179 } 180 @end 181 182 // <rdar://problem/11460990> 183 184 @interface WeirdNSString : NSString 185 - (id)initWithCString:(const char*)string, void *blah; 186 @end 187 188 189 // rdar://14121570 190 @protocol PMFilterManager 191 @end 192 193 @interface UIViewController : NSObject 194 @end 195 196 @implementation UIViewController 197 + (UIViewController<PMFilterManager> *)newFilterViewControllerForType // expected-note {{compiler has implicitly changed method 'newFilterViewControllerForType' return type}} 198 { 199 UIViewController<PMFilterManager> *filterVC; 200 return filterVC; // expected-warning {{incompatible pointer types casting 'UIViewController *' to type 'UIViewController<PMFilterManager> *'}} 201 } 202 @end 203