1*67e74705SXin Li// RUN: %clang_cc1 -fblocks -fsyntax-only -Wnullable-to-nonnull-conversion %s -verify 2*67e74705SXin Li// 3*67e74705SXin Li// Test the substitution of type arguments for type parameters when 4*67e74705SXin Li// using parameterized classes in Objective-C. 5*67e74705SXin Li 6*67e74705SXin Li@protocol NSObject 7*67e74705SXin Li@end 8*67e74705SXin Li 9*67e74705SXin Li__attribute__((objc_root_class)) 10*67e74705SXin Li@interface NSObject <NSObject> 11*67e74705SXin Li+ (instancetype)alloc; 12*67e74705SXin Li- (instancetype)init; 13*67e74705SXin Li@end 14*67e74705SXin Li 15*67e74705SXin Li@protocol NSCopying 16*67e74705SXin Li@end 17*67e74705SXin Li 18*67e74705SXin Li@interface NSString : NSObject <NSCopying> 19*67e74705SXin Li@end 20*67e74705SXin Li 21*67e74705SXin Li@interface NSMutableString : NSString 22*67e74705SXin Li@end 23*67e74705SXin Li 24*67e74705SXin Li@interface NSNumber : NSObject <NSCopying> 25*67e74705SXin Li@end 26*67e74705SXin Li 27*67e74705SXin Li@interface NSArray<T> : NSObject <NSCopying> { 28*67e74705SXin Li@public 29*67e74705SXin Li T *data; // don't try this at home 30*67e74705SXin Li} 31*67e74705SXin Li- (T)objectAtIndexedSubscript:(int)index; 32*67e74705SXin Li+ (NSArray<T> *)array; 33*67e74705SXin Li+ (void)setArray:(NSArray <T> *)array; 34*67e74705SXin Li@property (copy,nonatomic) T lastObject; 35*67e74705SXin Li@end 36*67e74705SXin Li 37*67e74705SXin Li@interface NSMutableArray<T> : NSArray<T> 38*67e74705SXin Li-(instancetype)initWithArray:(NSArray<T> *)array; // expected-note{{passing argument}} 39*67e74705SXin Li- (void)setObject:(T)object atIndexedSubscript:(int)index; // expected-note 2{{passing argument to parameter 'object' here}} 40*67e74705SXin Li@end 41*67e74705SXin Li 42*67e74705SXin Li@interface NSStringArray : NSArray<NSString *> 43*67e74705SXin Li@end 44*67e74705SXin Li 45*67e74705SXin Li@interface NSSet<T> : NSObject <NSCopying> 46*67e74705SXin Li- (T)firstObject; 47*67e74705SXin Li@property (nonatomic, copy) NSArray<T> *allObjects; 48*67e74705SXin Li@end 49*67e74705SXin Li 50*67e74705SXin Li// Parameterized inheritance (simple case) 51*67e74705SXin Li@interface NSMutableSet<U : id<NSCopying>> : NSSet<U> 52*67e74705SXin Li- (void)addObject:(U)object; // expected-note 7{{passing argument to parameter 'object' here}} 53*67e74705SXin Li@end 54*67e74705SXin Li 55*67e74705SXin Li@interface Widget : NSObject <NSCopying> 56*67e74705SXin Li@end 57*67e74705SXin Li 58*67e74705SXin Li// Non-parameterized class inheriting from a specialization of a 59*67e74705SXin Li// parameterized class. 60*67e74705SXin Li@interface WidgetSet : NSMutableSet<Widget *> 61*67e74705SXin Li@end 62*67e74705SXin Li 63*67e74705SXin Li// Parameterized inheritance with a more interesting transformation in 64*67e74705SXin Li// the specialization. 65*67e74705SXin Li@interface MutableSetOfArrays<T> : NSMutableSet<NSArray<T>*> 66*67e74705SXin Li@end 67*67e74705SXin Li 68*67e74705SXin Li// Inheriting from an unspecialized form of a parameterized type. 69*67e74705SXin Li@interface UntypedMutableSet : NSMutableSet 70*67e74705SXin Li@end 71*67e74705SXin Li 72*67e74705SXin Li@interface Window : NSObject 73*67e74705SXin Li@end 74*67e74705SXin Li 75*67e74705SXin Li@interface NSDictionary<K, V> : NSObject <NSCopying> 76*67e74705SXin Li- (V)objectForKeyedSubscript:(K)key; // expected-note 2{{parameter 'key'}} 77*67e74705SXin Li@end 78*67e74705SXin Li 79*67e74705SXin Li@interface NSMutableDictionary<K : id<NSCopying>, V> : NSDictionary<K, V> 80*67e74705SXin Li- (void)setObject:(V)object forKeyedSubscript:(K)key; 81*67e74705SXin Li// expected-note@-1 {{parameter 'object' here}} 82*67e74705SXin Li// expected-note@-2 {{parameter 'object' here}} 83*67e74705SXin Li// expected-note@-3 {{parameter 'key' here}} 84*67e74705SXin Li// expected-note@-4 {{parameter 'key' here}} 85*67e74705SXin Li 86*67e74705SXin Li@property (strong) K someRandomKey; 87*67e74705SXin Li@end 88*67e74705SXin Li 89*67e74705SXin Li@interface WindowArray : NSArray<Window *> 90*67e74705SXin Li@end 91*67e74705SXin Li 92*67e74705SXin Li@interface NSSet<T> (Searching) 93*67e74705SXin Li- (T)findObject:(T)object; 94*67e74705SXin Li@end 95*67e74705SXin Li 96*67e74705SXin Li@interface NSView : NSObject 97*67e74705SXin Li@end 98*67e74705SXin Li 99*67e74705SXin Li@interface NSControl : NSView 100*67e74705SXin Li- (void)toggle; 101*67e74705SXin Li@end 102*67e74705SXin Li 103*67e74705SXin Li@interface NSViewController<ViewType : NSView *> : NSObject 104*67e74705SXin Li@property (nonatomic,retain) ViewType view; 105*67e74705SXin Li@end 106*67e74705SXin Li 107*67e74705SXin Li// -------------------------------------------------------------------------- 108*67e74705SXin Li// Nullability 109*67e74705SXin Li// -------------------------------------------------------------------------- 110*67e74705SXin Litypedef NSControl * _Nonnull Nonnull_NSControl; 111*67e74705SXin Li 112*67e74705SXin Li@interface NSNullableTest<ViewType : NSView *> : NSObject 113*67e74705SXin Li- (ViewType)view; 114*67e74705SXin Li- (nullable ViewType)maybeView; 115*67e74705SXin Li@end 116*67e74705SXin Li 117*67e74705SXin Li@interface NSNullableTest2<ViewType : NSView * _Nullable> : NSObject // expected-error{{type parameter 'ViewType' bound 'NSView * _Nullable' cannot explicitly specify nullability}} 118*67e74705SXin Li@end 119*67e74705SXin Li 120*67e74705SXin Livoid test_nullability(void) { 121*67e74705SXin Li NSControl * _Nonnull nonnull_NSControl; 122*67e74705SXin Li 123*67e74705SXin Li // Nullability introduced by substitution. 124*67e74705SXin Li NSNullableTest<NSControl *> *unspecifiedControl; 125*67e74705SXin Li nonnull_NSControl = [unspecifiedControl view]; 126*67e74705SXin Li nonnull_NSControl = [unspecifiedControl maybeView]; // expected-warning{{from nullable pointer 'NSControl * _Nullable' to non-nullable pointer type 'NSControl * _Nonnull'}} 127*67e74705SXin Li 128*67e74705SXin Li // Nullability overridden by substitution. 129*67e74705SXin Li NSNullableTest<Nonnull_NSControl> *nonnullControl; 130*67e74705SXin Li nonnull_NSControl = [nonnullControl view]; 131*67e74705SXin Li nonnull_NSControl = [nonnullControl maybeView]; // expected-warning{{from nullable pointer 'Nonnull_NSControl _Nullable' (aka 'NSControl *') to non-nullable pointer type 'NSControl * _Nonnull'}} 132*67e74705SXin Li 133*67e74705SXin Li // Nullability cannot be specified directly on a type argument. 134*67e74705SXin Li NSNullableTest<NSControl * _Nonnull> *nonnullControl2; // expected-error{{type argument 'NSControl *' cannot explicitly specify nullability}} 135*67e74705SXin Li} 136*67e74705SXin Li 137*67e74705SXin Li// -------------------------------------------------------------------------- 138*67e74705SXin Li// Message sends. 139*67e74705SXin Li// -------------------------------------------------------------------------- 140*67e74705SXin Livoid test_message_send_result( 141*67e74705SXin Li NSSet<NSString *> *stringSet, 142*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 143*67e74705SXin Li WidgetSet *widgetSet, 144*67e74705SXin Li UntypedMutableSet *untypedMutSet, 145*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 146*67e74705SXin Li NSSet *set, 147*67e74705SXin Li NSMutableSet *mutSet, 148*67e74705SXin Li MutableSetOfArrays *mutArraySet, 149*67e74705SXin Li NSArray<NSString *> *stringArray, 150*67e74705SXin Li NSArray<__kindof NSString *> *kindofStringArray, 151*67e74705SXin Li void (^block)(void)) { 152*67e74705SXin Li int *ip; 153*67e74705SXin Li ip = [stringSet firstObject]; // expected-warning{{from 'NSString *'}} 154*67e74705SXin Li ip = [mutStringSet firstObject]; // expected-warning{{from 'NSString *'}} 155*67e74705SXin Li ip = [widgetSet firstObject]; // expected-warning{{from 'Widget *'}} 156*67e74705SXin Li ip = [untypedMutSet firstObject]; // expected-warning{{from 'id'}} 157*67e74705SXin Li ip = [mutStringArraySet firstObject]; // expected-warning{{from 'NSArray<NSString *> *'}} 158*67e74705SXin Li ip = [set firstObject]; // expected-warning{{from 'id'}} 159*67e74705SXin Li ip = [mutSet firstObject]; // expected-warning{{from 'id'}} 160*67e74705SXin Li ip = [mutArraySet firstObject]; // expected-warning{{from 'id'}} 161*67e74705SXin Li ip = [block firstObject]; // expected-warning{{from 'id'}} 162*67e74705SXin Li 163*67e74705SXin Li ip = [stringSet findObject:@"blah"]; // expected-warning{{from 'NSString *'}} 164*67e74705SXin Li 165*67e74705SXin Li // Class messages. 166*67e74705SXin Li ip = [NSSet<NSString *> alloc]; // expected-warning{{from 'NSSet<NSString *> *'}} 167*67e74705SXin Li ip = [NSSet alloc]; // expected-warning{{from 'NSSet *'}} 168*67e74705SXin Li ip = [MutableSetOfArrays<NSString *> alloc]; // expected-warning{{from 'MutableSetOfArrays<NSString *> *'}} 169*67e74705SXin Li ip = [MutableSetOfArrays alloc]; // expected-warning{{from 'MutableSetOfArrays *'}} 170*67e74705SXin Li ip = [NSArray<NSString *> array]; // expected-warning{{from 'NSArray<NSString *> *'}} 171*67e74705SXin Li ip = [NSArray<NSString *><NSCopying> array]; // expected-warning{{from 'NSArray<NSString *> *'}} 172*67e74705SXin Li 173*67e74705SXin Li ip = [[NSMutableArray<NSString *> alloc] init]; // expected-warning{{from 'NSMutableArray<NSString *> *'}} 174*67e74705SXin Li 175*67e74705SXin Li [[NSMutableArray alloc] initWithArray: stringArray]; // okay 176*67e74705SXin Li [[NSMutableArray<NSString *> alloc] initWithArray: stringArray]; // okay 177*67e74705SXin Li [[NSMutableArray<NSNumber *> alloc] initWithArray: stringArray]; // expected-warning{{sending 'NSArray<NSString *> *' to parameter of type 'NSArray<NSNumber *> *'}} 178*67e74705SXin Li 179*67e74705SXin Li ip = [[[NSViewController alloc] init] view]; // expected-warning{{from '__kindof NSView *'}} 180*67e74705SXin Li [[[[NSViewController alloc] init] view] toggle]; 181*67e74705SXin Li 182*67e74705SXin Li NSMutableString *mutStr = kindofStringArray[0]; 183*67e74705SXin Li NSNumber *number = kindofStringArray[0]; // expected-warning{{of type '__kindof NSString *'}} 184*67e74705SXin Li} 185*67e74705SXin Li 186*67e74705SXin Livoid test_message_send_param( 187*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 188*67e74705SXin Li WidgetSet *widgetSet, 189*67e74705SXin Li UntypedMutableSet *untypedMutSet, 190*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 191*67e74705SXin Li NSMutableSet *mutSet, 192*67e74705SXin Li MutableSetOfArrays *mutArraySet, 193*67e74705SXin Li void (^block)(void)) { 194*67e74705SXin Li Window *window; 195*67e74705SXin Li 196*67e74705SXin Li [mutStringSet addObject: window]; // expected-warning{{parameter of type 'NSString *'}} 197*67e74705SXin Li [widgetSet addObject: window]; // expected-warning{{parameter of type 'Widget *'}} 198*67e74705SXin Li [untypedMutSet addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}} 199*67e74705SXin Li [mutStringArraySet addObject: window]; // expected-warning{{parameter of type 'NSArray<NSString *> *'}} 200*67e74705SXin Li [mutSet addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}} 201*67e74705SXin Li [mutArraySet addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}} 202*67e74705SXin Li [block addObject: window]; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}} 203*67e74705SXin Li} 204*67e74705SXin Li 205*67e74705SXin Li// -------------------------------------------------------------------------- 206*67e74705SXin Li// Property accesses. 207*67e74705SXin Li// -------------------------------------------------------------------------- 208*67e74705SXin Livoid test_property_read( 209*67e74705SXin Li NSSet<NSString *> *stringSet, 210*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 211*67e74705SXin Li WidgetSet *widgetSet, 212*67e74705SXin Li UntypedMutableSet *untypedMutSet, 213*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 214*67e74705SXin Li NSSet *set, 215*67e74705SXin Li NSMutableSet *mutSet, 216*67e74705SXin Li MutableSetOfArrays *mutArraySet, 217*67e74705SXin Li NSMutableDictionary *mutDict) { 218*67e74705SXin Li int *ip; 219*67e74705SXin Li ip = stringSet.allObjects; // expected-warning{{from 'NSArray<NSString *> *'}} 220*67e74705SXin Li ip = mutStringSet.allObjects; // expected-warning{{from 'NSArray<NSString *> *'}} 221*67e74705SXin Li ip = widgetSet.allObjects; // expected-warning{{from 'NSArray<Widget *> *'}} 222*67e74705SXin Li ip = untypedMutSet.allObjects; // expected-warning{{from 'NSArray *'}} 223*67e74705SXin Li ip = mutStringArraySet.allObjects; // expected-warning{{from 'NSArray<NSArray<NSString *> *> *'}} 224*67e74705SXin Li ip = set.allObjects; // expected-warning{{from 'NSArray *'}} 225*67e74705SXin Li ip = mutSet.allObjects; // expected-warning{{from 'NSArray *'}} 226*67e74705SXin Li ip = mutArraySet.allObjects; // expected-warning{{from 'NSArray *'}} 227*67e74705SXin Li 228*67e74705SXin Li ip = mutDict.someRandomKey; // expected-warning{{from '__kindof id<NSCopying>'}} 229*67e74705SXin Li 230*67e74705SXin Li ip = [[NSViewController alloc] init].view; // expected-warning{{from '__kindof NSView *'}} 231*67e74705SXin Li} 232*67e74705SXin Li 233*67e74705SXin Livoid test_property_write( 234*67e74705SXin Li NSMutableSet<NSString *> *mutStringSet, 235*67e74705SXin Li WidgetSet *widgetSet, 236*67e74705SXin Li UntypedMutableSet *untypedMutSet, 237*67e74705SXin Li MutableSetOfArrays<NSString *> *mutStringArraySet, 238*67e74705SXin Li NSMutableSet *mutSet, 239*67e74705SXin Li MutableSetOfArrays *mutArraySet, 240*67e74705SXin Li NSMutableDictionary *mutDict) { 241*67e74705SXin Li int *ip; 242*67e74705SXin Li 243*67e74705SXin Li mutStringSet.allObjects = ip; // expected-warning{{to 'NSArray<NSString *> *'}} 244*67e74705SXin Li widgetSet.allObjects = ip; // expected-warning{{to 'NSArray<Widget *> *'}} 245*67e74705SXin Li untypedMutSet.allObjects = ip; // expected-warning{{to 'NSArray *'}} 246*67e74705SXin Li mutStringArraySet.allObjects = ip; // expected-warning{{to 'NSArray<NSArray<NSString *> *> *'}} 247*67e74705SXin Li mutSet.allObjects = ip; // expected-warning{{to 'NSArray *'}} 248*67e74705SXin Li mutArraySet.allObjects = ip; // expected-warning{{to 'NSArray *'}} 249*67e74705SXin Li 250*67e74705SXin Li mutDict.someRandomKey = ip; // expected-warning{{to 'id<NSCopying>'}} 251*67e74705SXin Li} 252*67e74705SXin Li 253*67e74705SXin Li// -------------------------------------------------------------------------- 254*67e74705SXin Li// Subscripting 255*67e74705SXin Li// -------------------------------------------------------------------------- 256*67e74705SXin Livoid test_subscripting( 257*67e74705SXin Li NSArray<NSString *> *stringArray, 258*67e74705SXin Li NSMutableArray<NSString *> *mutStringArray, 259*67e74705SXin Li NSArray *array, 260*67e74705SXin Li NSMutableArray *mutArray, 261*67e74705SXin Li NSDictionary<NSString *, Widget *> *stringWidgetDict, 262*67e74705SXin Li NSMutableDictionary<NSString *, Widget *> *mutStringWidgetDict, 263*67e74705SXin Li NSDictionary *dict, 264*67e74705SXin Li NSMutableDictionary *mutDict) { 265*67e74705SXin Li int *ip; 266*67e74705SXin Li NSString *string; 267*67e74705SXin Li Widget *widget; 268*67e74705SXin Li Window *window; 269*67e74705SXin Li 270*67e74705SXin Li ip = stringArray[0]; // expected-warning{{from 'NSString *'}} 271*67e74705SXin Li 272*67e74705SXin Li ip = mutStringArray[0]; // expected-warning{{from 'NSString *'}} 273*67e74705SXin Li mutStringArray[0] = ip; // expected-warning{{parameter of type 'NSString *'}} 274*67e74705SXin Li 275*67e74705SXin Li ip = array[0]; // expected-warning{{from 'id'}} 276*67e74705SXin Li 277*67e74705SXin Li ip = mutArray[0]; // expected-warning{{from 'id'}} 278*67e74705SXin Li mutArray[0] = ip; // expected-warning{{parameter of type 'id'}} 279*67e74705SXin Li 280*67e74705SXin Li ip = stringWidgetDict[string]; // expected-warning{{from 'Widget *'}} 281*67e74705SXin Li widget = stringWidgetDict[widget]; // expected-warning{{to parameter of type 'NSString *'}} 282*67e74705SXin Li 283*67e74705SXin Li ip = mutStringWidgetDict[string]; // expected-warning{{from 'Widget *'}} 284*67e74705SXin Li widget = mutStringWidgetDict[widget]; // expected-warning{{to parameter of type 'NSString *'}} 285*67e74705SXin Li mutStringWidgetDict[string] = ip; // expected-warning{{to parameter of type 'Widget *'}} 286*67e74705SXin Li mutStringWidgetDict[widget] = widget; // expected-warning{{to parameter of type 'NSString *'}} 287*67e74705SXin Li 288*67e74705SXin Li ip = dict[string]; // expected-warning{{from 'id'}} 289*67e74705SXin Li 290*67e74705SXin Li ip = mutDict[string]; // expected-warning{{from 'id'}} 291*67e74705SXin Li mutDict[string] = ip; // expected-warning{{to parameter of type 'id'}} 292*67e74705SXin Li 293*67e74705SXin Li widget = mutDict[window]; 294*67e74705SXin Li mutDict[window] = widget; // expected-warning{{parameter of incompatible type 'id<NSCopying>'}} 295*67e74705SXin Li} 296*67e74705SXin Li 297*67e74705SXin Li// -------------------------------------------------------------------------- 298*67e74705SXin Li// Instance variable access. 299*67e74705SXin Li// -------------------------------------------------------------------------- 300*67e74705SXin Livoid test_instance_variable(NSArray<NSString *> *stringArray, 301*67e74705SXin Li NSArray *array) { 302*67e74705SXin Li int *ip; 303*67e74705SXin Li 304*67e74705SXin Li ip = stringArray->data; // expected-warning{{from 'NSString **'}} 305*67e74705SXin Li ip = array->data; // expected-warning{{from 'id *'}} 306*67e74705SXin Li} 307*67e74705SXin Li 308*67e74705SXin Li@implementation WindowArray 309*67e74705SXin Li- (void)testInstanceVariable { 310*67e74705SXin Li int *ip; 311*67e74705SXin Li 312*67e74705SXin Li ip = data; // expected-warning{{from 'Window **'}} 313*67e74705SXin Li} 314*67e74705SXin Li@end 315*67e74705SXin Li 316*67e74705SXin Li// -------------------------------------------------------------------------- 317*67e74705SXin Li// Implicit conversions. 318*67e74705SXin Li// -------------------------------------------------------------------------- 319*67e74705SXin Livoid test_implicit_conversions(NSArray<NSString *> *stringArray, 320*67e74705SXin Li NSArray<NSNumber *> *numberArray, 321*67e74705SXin Li NSMutableArray<NSString *> *mutStringArray, 322*67e74705SXin Li NSArray *array, 323*67e74705SXin Li NSMutableArray *mutArray) { 324*67e74705SXin Li // Specialized -> unspecialized (same level) 325*67e74705SXin Li array = stringArray; 326*67e74705SXin Li 327*67e74705SXin Li // Unspecialized -> specialized (same level) 328*67e74705SXin Li stringArray = array; 329*67e74705SXin Li 330*67e74705SXin Li // Specialized -> specialized failure (same level). 331*67e74705SXin Li stringArray = numberArray; // expected-warning{{incompatible pointer types assigning to 'NSArray<NSString *> *' from 'NSArray<NSNumber *> *'}} 332*67e74705SXin Li 333*67e74705SXin Li // Specialized -> specialized (different levels). 334*67e74705SXin Li stringArray = mutStringArray; 335*67e74705SXin Li 336*67e74705SXin Li // Specialized -> specialized failure (different levels). 337*67e74705SXin Li numberArray = mutStringArray; // expected-warning{{incompatible pointer types assigning to 'NSArray<NSNumber *> *' from 'NSMutableArray<NSString *> *'}} 338*67e74705SXin Li 339*67e74705SXin Li // Unspecialized -> specialized (different levels). 340*67e74705SXin Li stringArray = mutArray; 341*67e74705SXin Li 342*67e74705SXin Li // Specialized -> unspecialized (different levels). 343*67e74705SXin Li array = mutStringArray; 344*67e74705SXin Li} 345*67e74705SXin Li 346*67e74705SXin Li@interface NSCovariant1<__covariant T> 347*67e74705SXin Li@end 348*67e74705SXin Li 349*67e74705SXin Li@interface NSContravariant1<__contravariant T> 350*67e74705SXin Li@end 351*67e74705SXin Li 352*67e74705SXin Livoid test_variance(NSCovariant1<NSString *> *covariant1, 353*67e74705SXin Li NSCovariant1<NSMutableString *> *covariant2, 354*67e74705SXin Li NSCovariant1<NSString *(^)(void)> *covariant3, 355*67e74705SXin Li NSCovariant1<NSMutableString *(^)(void)> *covariant4, 356*67e74705SXin Li NSCovariant1<id> *covariant5, 357*67e74705SXin Li NSCovariant1<id<NSCopying>> *covariant6, 358*67e74705SXin Li NSContravariant1<NSString *> *contravariant1, 359*67e74705SXin Li NSContravariant1<NSMutableString *> *contravariant2) { 360*67e74705SXin Li covariant1 = covariant2; // okay 361*67e74705SXin Li covariant2 = covariant1; // expected-warning{{incompatible pointer types assigning to 'NSCovariant1<NSMutableString *> *' from 'NSCovariant1<NSString *> *'}} 362*67e74705SXin Li 363*67e74705SXin Li covariant3 = covariant4; // okay 364*67e74705SXin Li covariant4 = covariant3; // expected-warning{{incompatible pointer types assigning to 'NSCovariant1<NSMutableString *(^)(void)> *' from 'NSCovariant1<NSString *(^)(void)> *'}} 365*67e74705SXin Li 366*67e74705SXin Li covariant5 = covariant1; // okay 367*67e74705SXin Li covariant1 = covariant5; // okay: id is promiscuous 368*67e74705SXin Li 369*67e74705SXin Li covariant5 = covariant3; // okay 370*67e74705SXin Li covariant3 = covariant5; // okay 371*67e74705SXin Li 372*67e74705SXin Li contravariant1 = contravariant2; // expected-warning{{incompatible pointer types assigning to 'NSContravariant1<NSString *> *' from 'NSContravariant1<NSMutableString *> *'}} 373*67e74705SXin Li contravariant2 = contravariant1; // okay 374*67e74705SXin Li} 375*67e74705SXin Li 376*67e74705SXin Li// -------------------------------------------------------------------------- 377*67e74705SXin Li// Ternary operator 378*67e74705SXin Li// -------------------------------------------------------------------------- 379*67e74705SXin Livoid test_ternary_operator(NSArray<NSString *> *stringArray, 380*67e74705SXin Li NSArray<NSNumber *> *numberArray, 381*67e74705SXin Li NSMutableArray<NSString *> *mutStringArray, 382*67e74705SXin Li NSStringArray *stringArray2, 383*67e74705SXin Li NSArray *array, 384*67e74705SXin Li NSMutableArray *mutArray, 385*67e74705SXin Li int cond) { 386*67e74705SXin Li int *ip; 387*67e74705SXin Li id object; 388*67e74705SXin Li 389*67e74705SXin Li ip = cond ? stringArray : mutStringArray; // expected-warning{{from 'NSArray<NSString *> *'}} 390*67e74705SXin Li ip = cond ? mutStringArray : stringArray; // expected-warning{{from 'NSArray<NSString *> *'}} 391*67e74705SXin Li 392*67e74705SXin Li ip = cond ? stringArray2 : mutStringArray; // expected-warning{{from 'NSArray<NSString *> *'}} 393*67e74705SXin Li ip = cond ? mutStringArray : stringArray2; // expected-warning{{from 'NSArray<NSString *> *'}} 394*67e74705SXin Li 395*67e74705SXin Li ip = cond ? stringArray : mutArray; // expected-warning{{from 'NSArray *'}} 396*67e74705SXin Li 397*67e74705SXin Li ip = cond ? stringArray2 : mutArray; // expected-warning{{from 'NSArray *'}} 398*67e74705SXin Li 399*67e74705SXin Li ip = cond ? mutArray : stringArray; // expected-warning{{from 'NSArray *'}} 400*67e74705SXin Li 401*67e74705SXin Li ip = cond ? mutArray : stringArray2; // expected-warning{{from 'NSArray *'}} 402*67e74705SXin Li 403*67e74705SXin Li object = cond ? stringArray : numberArray; // expected-warning{{incompatible operand types ('NSArray<NSString *> *' and 'NSArray<NSNumber *> *')}} 404*67e74705SXin Li} 405*67e74705SXin Li 406*67e74705SXin Li// -------------------------------------------------------------------------- 407*67e74705SXin Li// super 408*67e74705SXin Li// -------------------------------------------------------------------------- 409*67e74705SXin Li@implementation NSStringArray 410*67e74705SXin Li- (void)useSuperMethod { 411*67e74705SXin Li int *ip; 412*67e74705SXin Li ip = super.lastObject; // expected-warning{{from 'NSString *'}} 413*67e74705SXin Li super.lastObject = ip; // expected-warning{{to 'NSString *'}} 414*67e74705SXin Li ip = [super objectAtIndexedSubscript:0]; // expected-warning{{from 'NSString *'}} 415*67e74705SXin Li} 416*67e74705SXin Li 417*67e74705SXin Li+ (void)useSuperMethod { 418*67e74705SXin Li int *ip; 419*67e74705SXin Li ip = super.array; // expected-warning{{from 'NSArray<NSString *> *'}} 420*67e74705SXin Li super.array = ip; // expected-warning{{to 'NSArray<NSString *> *'}} 421*67e74705SXin Li ip = [super array]; // expected-warning{{from 'NSArray<NSString *> *'}} 422*67e74705SXin Li} 423*67e74705SXin Li@end 424*67e74705SXin Li 425*67e74705SXin Li// -------------------------------------------------------------------------- 426*67e74705SXin Li// warning about likely protocol/class name typos. 427*67e74705SXin Li// -------------------------------------------------------------------------- 428*67e74705SXin Litypedef NSArray<NSObject> ArrayOfNSObjectWarning; // expected-warning{{parameterized class 'NSArray' already conforms to the protocols listed; did you forget a '*'?}} 429