1 // RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc -fobjc-runtime=macosx-fragile-10.5 %s -o %t-rw.cpp 2 // RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp 3 // RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fms-extensions -rewrite-objc %s -o %t-modern-rw.cpp 4 // RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-modern-rw.cpp 5 6 void *sel_registerName(const char *); 7 8 @interface Root 9 + (instancetype)alloc; 10 - (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}} 11 - (instancetype)self; 12 - (Class)class; 13 14 @property (assign) Root *selfProp; 15 - (instancetype)selfProp; 16 @end 17 18 @protocol Proto1 19 @optional 20 - (instancetype)methodInProto1; 21 @end 22 23 @protocol Proto2 24 @optional 25 - (instancetype)methodInProto2; // expected-note{{overridden method returns an instance of its class type}} 26 - (instancetype)otherMethodInProto2; // expected-note{{overridden method returns an instance of its class type}} 27 @end 28 29 @interface Subclass1 : Root 30 - (instancetype)initSubclass1; 31 - (void)methodOnSubclass1; 32 + (instancetype)allocSubclass1; 33 @end 34 35 @interface Subclass2 : Root 36 - (instancetype)initSubclass2; 37 - (void)methodOnSubclass2; 38 @end 39 40 // Sanity check: the basic initialization pattern. 41 void test_instancetype_alloc_init_simple() { 42 Root *r1 = [[Root alloc] init]; 43 Subclass1 *sc1 = [[Subclass1 alloc] init]; 44 } 45 46 // Test that message sends to instancetype methods have the right type. 47 void test_instancetype_narrow_method_search() { 48 // instancetype on class methods 49 Subclass1 *sc1 = [[Subclass1 alloc] initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}} 50 Subclass2 *sc2 = [[Subclass2 alloc] initSubclass2]; // okay 51 52 // instancetype on instance methods 53 [[[Subclass1 alloc] init] methodOnSubclass2]; // expected-warning{{'Subclass1' may not respond to 'methodOnSubclass2'}} 54 [[[Subclass2 alloc] init] methodOnSubclass2]; 55 56 // instancetype on class methods using protocols 57 [[Subclass1<Proto1> alloc] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} 58 [[Subclass1<Proto2> alloc] methodInProto2]; 59 60 // instancetype on instance methods 61 Subclass1<Proto1> *sc1proto1 = 0; 62 [[sc1proto1 self] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} 63 Subclass1<Proto2> *sc1proto2 = 0; 64 [[sc1proto2 self] methodInProto2]; 65 66 // Exact type checks 67 // Message sends to Class. 68 // FIXME. This is not supported due to missing capability in rewriter and not due to instancetype issues 69 // Subclass1<Proto1> *sc1proto1_2 = [[[sc1proto1 class] alloc] init]; 70 71 // Property access 72 [sc1proto1.self methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} 73 [sc1proto2.self methodInProto2]; 74 75 [sc1proto1.selfProp methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}} 76 [sc1proto2.selfProp methodInProto2]; 77 } 78