1acfbe9e1SPatrick Beard// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wno-objc-root-class %s 289026888SChris Lattner@protocol NSObject 389026888SChris Lattner@end 489026888SChris Lattner 589026888SChris Lattner@protocol DTOutputStreams <NSObject> 689026888SChris Lattner@end 789026888SChris Lattner 889026888SChris Lattner@interface DTFilterOutputStream <DTOutputStreams> 989026888SChris Lattner- nextOutputStream; 1089026888SChris Lattner@end 1189026888SChris Lattner 1289026888SChris Lattner@implementation DTFilterOutputStream 1389026888SChris Lattner- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { 1489026888SChris Lattner id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; 1589026888SChris Lattner self = nextOutputStream; 1689026888SChris Lattner return nextOutputStream ? nextOutputStream : self; 1789026888SChris Lattner} 1889026888SChris Lattner- nextOutputStream { 1989026888SChris Lattner return self; 2089026888SChris Lattner} 2189026888SChris Lattner@end 2289026888SChris Lattner 2389026888SChris Lattner@interface DTFilterOutputStream2 2465d63577STed Kremenek- nextOutputStream; // expected-note {{method 'nextOutputStream' declared here}} 2589026888SChris Lattner@end 2689026888SChris Lattner 2765d63577STed Kremenek@implementation DTFilterOutputStream2 // expected-warning {{method definition for 'nextOutputStream' not found}} 2889026888SChris Lattner- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { 2989026888SChris Lattner id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; 30c68e1406SDouglas Gregor self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream2 *' from incompatible type 'id<DTOutputStreams>'}} 318e6aee58SSteve Naroff return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream2 *')}} 3289026888SChris Lattner} 3389026888SChris Lattner@end 3489026888SChris Lattner 3589026888SChris Lattner// No @interface declaration for DTFilterOutputStream3 36773df4a1SFariborz Jahanian@implementation DTFilterOutputStream3 // expected-warning {{cannot find interface declaration for 'DTFilterOutputStream3'}} \ 37478536b1SFariborz Jahanian // expected-note {{receiver is instance of class declared here}} 3889026888SChris Lattner- (id)initWithNextOutputStream:(id <DTOutputStreams>) outputStream { 393f49feeeSSteve Naroff id <DTOutputStreams> nextOutputStream = [self nextOutputStream]; // expected-warning {{method '-nextOutputStream' not found (return type defaults to 'id')}} 40c68e1406SDouglas Gregor self = nextOutputStream; // expected-warning {{assigning to 'DTFilterOutputStream3 *' from incompatible type 'id<DTOutputStreams>'}} 418e6aee58SSteve Naroff return nextOutputStream ? nextOutputStream : self; // expected-warning {{incompatible operand types ('id<DTOutputStreams>' and 'DTFilterOutputStream3 *')}} 4289026888SChris Lattner} 4389026888SChris Lattner@end 440418a5f1SDaniel Dunbar 450418a5f1SDaniel Dunbar// 460418a5f1SDaniel Dunbar 470418a5f1SDaniel Dunbar@protocol P0 480418a5f1SDaniel Dunbar@property int intProp; 490418a5f1SDaniel Dunbar@end 500418a5f1SDaniel Dunbar@protocol P1 510418a5f1SDaniel Dunbar@end 520418a5f1SDaniel Dunbar@protocol P2 530418a5f1SDaniel Dunbar@end 54*c5e07f5cSDouglas Gregor@protocol P3 <P1> 55*c5e07f5cSDouglas Gregor@end 56*c5e07f5cSDouglas Gregor@protocol P4 <P1> 57*c5e07f5cSDouglas Gregor@end 580418a5f1SDaniel Dunbar 590418a5f1SDaniel Dunbar@interface A <P0> 600418a5f1SDaniel Dunbar@end 610418a5f1SDaniel Dunbar 620418a5f1SDaniel Dunbar@interface B : A 630418a5f1SDaniel Dunbar@end 640418a5f1SDaniel Dunbar 650418a5f1SDaniel Dunbar@interface C 660418a5f1SDaniel Dunbar@end 670418a5f1SDaniel Dunbar 680418a5f1SDaniel Dunbar@interface D 690418a5f1SDaniel Dunbar@end 700418a5f1SDaniel Dunbar 71*c5e07f5cSDouglas Gregor@interface E : A 72*c5e07f5cSDouglas Gregor@end 73*c5e07f5cSDouglas Gregor 740418a5f1SDaniel Dunbarvoid f0(id<P0> x) { 750418a5f1SDaniel Dunbar x.intProp = 1; 760418a5f1SDaniel Dunbar} 770418a5f1SDaniel Dunbar 780418a5f1SDaniel Dunbarvoid f1(int cond, id<P0> x, id<P0> y) { 790418a5f1SDaniel Dunbar (cond ? x : y).intProp = 1; 800418a5f1SDaniel Dunbar} 810418a5f1SDaniel Dunbar 820418a5f1SDaniel Dunbarvoid f2(int cond, id<P0> x, A *y) { 830418a5f1SDaniel Dunbar (cond ? x : y).intProp = 1; 840418a5f1SDaniel Dunbar} 850418a5f1SDaniel Dunbar 860418a5f1SDaniel Dunbarvoid f3(int cond, id<P0> x, B *y) { 870418a5f1SDaniel Dunbar (cond ? x : y).intProp = 1; 880418a5f1SDaniel Dunbar} 890418a5f1SDaniel Dunbar 900418a5f1SDaniel Dunbarvoid f4(int cond, id x, B *y) { 910418a5f1SDaniel Dunbar (cond ? x : y).intProp = 1; // expected-error {{property 'intProp' not found on object of type 'id'}} 920418a5f1SDaniel Dunbar} 930418a5f1SDaniel Dunbar 940418a5f1SDaniel Dunbarvoid f5(int cond, id<P0> x, C *y) { 958e6aee58SSteve Naroff (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types ('id<P0>' and 'C *')}} expected-error {{property 'intProp' not found on object of type 'id'}} 960418a5f1SDaniel Dunbar} 970418a5f1SDaniel Dunbar 980418a5f1SDaniel Dunbarvoid f6(int cond, C *x, D *y) { 990418a5f1SDaniel Dunbar (cond ? x : y).intProp = 1; // expected-warning {{incompatible operand types}}, expected-error {{property 'intProp' not found on object of type 'id'}} 1000418a5f1SDaniel Dunbar} 101a3f41f4bSDaniel Dunbar 102a3f41f4bSDaniel Dunbarid f7(int a, id<P0> x, A* p) { 103a3f41f4bSDaniel Dunbar return a ? x : p; 104a3f41f4bSDaniel Dunbar} 105a3f41f4bSDaniel Dunbar 106ac6b4efaSFariborz Jahanianint f8(int a, A<P0> *x, A *y) { 107ac6b4efaSFariborz Jahanian return [ (a ? x : y ) intProp ]; 108a3f41f4bSDaniel Dunbar} 109a3f41f4bSDaniel Dunbar 110a3f41f4bSDaniel Dunbarvoid f9(int a, A<P0> *x, A<P1> *y) { 11112f7ef39SFariborz Jahanian id l0 = (a ? x : y ); // Ok. y is of A<P1> object type and A is qualified by P0. 11212f7ef39SFariborz Jahanian A<P0> *l1 = (a ? x : y ); // Ok. y is of A<P1> object type and A is qualified by P0. 11312f7ef39SFariborz Jahanian A<P1> *l2 = (a ? x : y ); // expected-warning {{incompatible pointer types initializing 'A<P1> *' with an expression of type 'A<P0> *'}} 11412f7ef39SFariborz Jahanian (void)[ (a ? x : y ) intProp ]; // Ok. Common type is A<P0> * and P0's property intProp is accessed. 115a3f41f4bSDaniel Dunbar} 116a3f41f4bSDaniel Dunbar 117a3f41f4bSDaniel Dunbarvoid f10(int a, id<P0> x, id y) { 118a3f41f4bSDaniel Dunbar [ (a ? x : y ) intProp ]; 119a3f41f4bSDaniel Dunbar} 120a3f41f4bSDaniel Dunbar 121a3f41f4bSDaniel Dunbarvoid f11(int a, id<P0> x, id<P1> y) { 122a3f41f4bSDaniel Dunbar [ (a ? x : y ) intProp ]; // expected-warning {{incompatible operand types ('id<P0>' and 'id<P1>')}} 123a3f41f4bSDaniel Dunbar} 124a3f41f4bSDaniel Dunbar 125a3f41f4bSDaniel Dunbarvoid f12(int a, A<P0> *x, A<P1> *y) { 12612f7ef39SFariborz Jahanian A<P1>* l0 = (a ? x : y ); // expected-warning {{incompatible pointer types initializing 'A<P1> *' with an expression of type 'A<P0> *'}} 127a3f41f4bSDaniel Dunbar} 128*c5e07f5cSDouglas Gregor 129*c5e07f5cSDouglas Gregorvoid f13(int a, B<P3, P0> *x, E<P0, P4> *y) { 130*c5e07f5cSDouglas Gregor int *ip = a ? x : y; // expected-warning{{expression of type 'A<P1> *'}} 131*c5e07f5cSDouglas Gregor} 132