1// RUN: %clang_cc1 -fsyntax-only -verify %s
2
3@protocol P0
4@end
5@protocol P1
6@end
7@protocol P2
8@end
9
10@interface A <P0>
11@end
12
13@interface B : A
14@end
15
16void bar(id x);
17void barP0(id<P0> x);
18void barP1(id<P1> x);
19void barP2(id<P2> x);
20
21void f0(A *a) {
22  id l = a;
23}
24
25void f1(id x, A *a) {
26  id<P0> l = a;
27}
28
29void f2(id<P1> x) {
30  id<P0> l = x; // expected-error {{cannot initialize a variable of type 'id<P0>' with an lvalue of type 'id<P1>'}}
31}
32
33void f3(A *a) {
34  id<P1> l = a; // expected-error {{cannot initialize a variable of type 'id<P1>' with an lvalue of type 'A *'}}
35}
36
37void f4(int cond, id x, A *a) {
38  bar(cond ? x : a);
39}
40
41void f5(int cond, A *a, B *b) {
42  bar(cond ? a : b);
43}
44
45void f6(int cond, id x, A *a) {
46  bar(cond ? (id<P0, P1>) x : a);
47}
48
49void f7(int cond, id x, A *a) {
50  bar(cond ? a : (id<P0, P1>) x);
51}
52
53void f8(int cond, id<P0,P1> x0, id<P0,P2> x1) {
54  barP0(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
55}
56
57void f9(int cond, id<P0,P1> x0, id<P0,P2> x1) {
58  barP1(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
59}
60
61void f10(int cond, id<P0,P1> x0, id<P0,P2> x1) {
62  barP2(cond ? x0 : x1); // expected-warning {{incompatible operand types ('id<P0,P1>' and 'id<P0,P2>')}}
63}
64
65int f11(int cond, A* a, B* b) {
66  return (cond? b : a)->x; // expected-error{{'A' does not have a member named 'x'}}
67}
68