80 lines · plain
1// RUN: %clang_cc1 -fsyntax-only -verify %s2 3#define nil ((void*) 0)4 5@interface A 6@property int x;7@end8 9@interface B : A10@end11 12// Basic checks...13id f0(int cond, id a, void *b) {14 return cond ? a : b;15}16A *f0_a(int cond, A *a, void *b) {17 return cond ? a : b;18}19 20id f1(int cond, id a) {21 return cond ? a : nil;22}23A *f1_a(int cond, A *a) {24 return cond ? a : nil;25}26 27void *f1_const_a(int x, void *p, const A * q) {28 void *r = x ? p : q; // expected-warning{{initializing 'void *' with an expression of type 'const void *' discards qualifiers}}29 return r;30}31 32// Check interaction with qualified id33 34@protocol P0 @end35 36id f2(int cond, id<P0> a, void *b) {37 return cond ? a : b;38}39 40id f3(int cond, id<P0> a) {41 return cond ? a : nil;42}43 44// Check that result actually has correct type.45 46// Using properties is one way to find the compiler internal type of a47// conditional expression. Simple assignment doesn't work because if48// the type is id then it can be implicitly promoted.49@protocol P150@property int x;51@end52 53int f5(int cond, id<P1> a, id<P1> b) {54 return (cond ? a : b).x;55}56int f5_a(int cond, A *a, A *b) {57 return (cond ? a : b).x;58}59int f5_b(int cond, A *a, B *b) {60 return (cond ? a : b).x;61}62 63int f6(int cond, id<P1> a, void *b) {64 // This should result in something with id type, currently.65 return (cond ? a : b).x; // expected-error {{member reference base type 'void *' is not a structure or union}}66}67 68int f7(int cond, id<P1> a) {69 return (cond ? a : nil).x;70}71 72int f8(int cond, id<P1> a, A *b) {73 return a == b; // expected-warning {{comparison of distinct pointer types ('id<P1>' and 'A *')}}74}75 76int f9(int cond, id<P1> a, A *b) {77 return (cond ? a : b).x; // expected-warning {{incompatible operand types ('id<P1>' and 'A *')}} \78 expected-error {{property 'x' not found on object of type 'id'}}79}80