brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 5e479f5 Raw
223 lines · plain
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3#if !__has_feature(objc_instancetype)4# error Missing 'instancetype' feature macro.5#endif6 7@interface Root8+ (instancetype)alloc; // expected-note {{explicitly declared 'instancetype'}}9- (instancetype)init; // expected-note{{overridden method is part of the 'init' method family}}10- (instancetype)self; // expected-note {{explicitly declared 'instancetype'}}11- (Class)class;12 13@property (assign) Root *selfProp;14- (instancetype)selfProp;15@end16 17@protocol Proto118@optional19- (instancetype)methodInProto1;20@end21 22@protocol Proto223@optional24- (instancetype)methodInProto2; // expected-note{{overridden method returns an instance of its class type}}25- (instancetype)otherMethodInProto2; // expected-note{{overridden method returns an instance of its class type}}26@end27 28@interface Subclass1 : Root // expected-note 4 {{receiver is instance of class declared here}}29- (instancetype)initSubclass1;30- (void)methodOnSubclass1;31+ (instancetype)allocSubclass1;32@end33 34@interface Subclass2 : Root35- (instancetype)initSubclass2;36- (void)methodOnSubclass2;37@end38 39// Verify the basic initialization pattern.40void test_instancetype_alloc_init_simple() {41  Root *r1 = [[Root alloc] init];42  Subclass1 *sc1 = [[Subclass1 alloc] init];43}44 45// Test that message sends to instancetype methods have the right type.46void test_instancetype_narrow_method_search() {47  // instancetype on class methods48  Subclass1 *sc1 = [[Subclass1 alloc] initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}}49  Subclass2 *sc2 = [[Subclass2 alloc] initSubclass2]; // okay50 51  // instancetype on instance methods52  [[[Subclass1 alloc] init] methodOnSubclass2]; // expected-warning{{'Subclass1' may not respond to 'methodOnSubclass2'}}53  [[[Subclass2 alloc] init] methodOnSubclass2];54  55  // instancetype on class methods using protocols56  typedef Subclass1<Proto1> SC1Proto1;57  typedef Subclass1<Proto2> SC1Proto2;58  [[SC1Proto1 alloc] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}59  [[SC1Proto2 alloc] methodInProto2];60 61  // instancetype on instance methods62  Subclass1<Proto1> *sc1proto1 = 0;63  [[sc1proto1 self] methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}64  Subclass1<Proto2> *sc1proto2 = 0;65  [[sc1proto2 self] methodInProto2];66 67  // Exact type checks68  typeof([[Subclass1 alloc] init]) *ptr1 = (Subclass1 **)0;69  typeof([[Subclass2 alloc] init]) *ptr2 = (Subclass2 **)0;70 71  // Message sends to Class.72  Subclass1<Proto1> *sc1proto1_2 = [[[sc1proto1 class] alloc] init];73 74  // Property access75  [sc1proto1.self methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}76  [sc1proto2.self methodInProto2];77  [Subclass1.alloc initSubclass2]; // expected-warning{{'Subclass1' may not respond to 'initSubclass2'}}78  [Subclass2.alloc initSubclass2];79 80  [sc1proto1.selfProp methodInProto2]; // expected-warning{{method '-methodInProto2' not found (return type defaults to 'id')}}81  [sc1proto2.selfProp methodInProto2];82}83 84// Test that message sends to super methods have the right type.85@interface Subsubclass1 : Subclass186- (instancetype)initSubclass1;87+ (instancetype)allocSubclass1;88 89- (void)onlyInSubsubclass1;90@end91 92@implementation Subsubclass193- (instancetype)initSubclass1 {94  // Check based on method search.95  [[super initSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}96  [super.initSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}97 98  self = [super init]; // common pattern99 100  // Exact type check.101  typeof([super initSubclass1]) *ptr1 = (Subsubclass1**)0;102 103  return self;104}105 106+ (instancetype)allocSubclass1 {107  // Check based on method search.108  [[super allocSubclass1] methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}109 110  // The ASTs don't model super property accesses well enough to get this right111  [super.allocSubclass1 methodOnSubclass2]; // expected-warning{{'Subsubclass1' may not respond to 'methodOnSubclass2'}}112 113  // Exact type check.114  typeof([super allocSubclass1]) *ptr1 = (Subsubclass1**)0;115  116  return [super allocSubclass1];117}118 119- (void)onlyInSubsubclass1 {}120@end121 122// Check compatibility rules for inheritance of related return types.123@class Subclass4;124 125@interface Subclass3 <Proto1, Proto2>126- (Subclass3 *)methodInProto1;127- (Subclass4 *)methodInProto2; // expected-warning{{method is expected to return an instance of its class type 'Subclass3', but is declared to return 'Subclass4 *'}}128@end129 130@interface Subclass4 : Root131+ (Subclass4 *)alloc; // okay132- (Subclass3 *)init; // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}}133- (id)self; // expected-note{{overridden method is part of the 'self' method family}}134- (instancetype)initOther;135@end136 137@protocol Proto3 <Proto1, Proto2>138@optional139- (id)methodInProto1;140- (Subclass1 *)methodInProto2;141- (int)otherMethodInProto2; // expected-warning{{protocol method is expected to return an instance of the implementing class, but is declared to return 'int'}}142@end143 144@implementation Subclass4145+ (id)alloc {146  return self; // expected-error{{cannot initialize return object of type 'Subclass4 *' with an lvalue of type 'Class'}}147}148 149- (Subclass3 *)init { return 0; } // don't complain: we lost the related return type150 151- (Subclass3 *)self { return 0; } // expected-warning{{method is expected to return an instance of its class type 'Subclass4', but is declared to return 'Subclass3 *'}}152 153- (Subclass4 *)initOther { return 0; }154 155@end156 157// Check that inherited related return types influence the types of158// message sends.159void test_instancetype_inherited() {160  [[Subclass4 alloc] initSubclass1]; // expected-warning{{'Subclass4' may not respond to 'initSubclass1'}}161  [[Subclass4 alloc] initOther];162}163 164// Check that related return types tighten up the semantics of165// Objective-C method implementations.166@implementation Subclass2167- (instancetype)initSubclass2 { // expected-note {{explicitly declared 'instancetype'}}168  Subclass1 *sc1 = [[Subclass1 alloc] init];169  return sc1; // expected-error{{cannot initialize return object of type 'Subclass2 *' with an lvalue of type 'Subclass1 *'}}170}171- (void)methodOnSubclass2 {}172- (id)self {173  Subclass1 *sc1 = [[Subclass1 alloc] init];174  return sc1; // expected-error{{cannot initialize return object of type 'Subclass2 *' with an lvalue of type 'Subclass1 *'}}175}176@end177 178@interface MyClass : Root179+ (int)myClassMethod;180@end181 182@implementation MyClass183+ (int)myClassMethod { return 0; }184 185- (void)blah {186  int i = [[MyClass self] myClassMethod];187}188 189@end190 191@protocol P4192- (instancetype) foo; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}}193@end194@interface A4 : Root <P4>195- (instancetype) bar; // expected-note {{current method is explicitly declared 'instancetype' and is expected to return an instance of its class type}}196- (instancetype) baz; // expected-note {{overridden method returns an instance of its class type}} expected-note {{previous definition is here}}197@end198@interface B4 : Root @end199 200@implementation A4 {201  B4 *_b;202}203- (id) foo {204  return _b; // expected-error {{cannot initialize return object of type 'A4 *' with an lvalue of type 'B4 *'}}205}206- (id) bar {207  return _b; // expected-error {{cannot initialize return object of type 'A4 *' with an lvalue of type 'B4 *'}}208}209 210// This is really just to ensure that we don't crash.211// FIXME: only one diagnostic, please212- (float) baz { // expected-warning {{method is expected to return an instance of its class type 'A4', but is declared to return 'float'}} expected-warning {{conflicting return type in implementation}}213  return 0;214}215@end216 217// PR27822218@class NSString;219namespace pr27822 { }220@interface AXPlatformNodeCocoa221+ (NSString*)nativeRoleFromAXRole:(pr27822::UndeclaredIdentifier)role; // expected-error {{expected a type}}222@end223