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