xref: /aosp_15_r20/external/clang/test/SemaObjCXX/conversion-ranking.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li// expected-no-diagnostics
3*67e74705SXin Li@protocol P1
4*67e74705SXin Li@end
5*67e74705SXin Li
6*67e74705SXin Li@interface A <P1>
7*67e74705SXin Li@end
8*67e74705SXin Li
9*67e74705SXin Li@interface B : A
10*67e74705SXin Li@end
11*67e74705SXin Li
12*67e74705SXin Li@interface C : B
13*67e74705SXin Li@end
14*67e74705SXin Li
15*67e74705SXin Litemplate<typename T>
16*67e74705SXin Listruct ConvertsTo {
17*67e74705SXin Li  operator T() const;
18*67e74705SXin Li};
19*67e74705SXin Li
20*67e74705SXin Li
21*67e74705SXin Li// conversion of C* to B* is better than conversion of C* to A*.
22*67e74705SXin Liint &f0(A*);
23*67e74705SXin Lifloat &f0(B*);
24*67e74705SXin Li
25*67e74705SXin Livoid test_f0(C *c) {
26*67e74705SXin Li  float &fr1 = f0(c);
27*67e74705SXin Li}
28*67e74705SXin Li
29*67e74705SXin Li// conversion of B* to A* is better than conversion of C* to A*
30*67e74705SXin Livoid f1(A*);
31*67e74705SXin Li
32*67e74705SXin Listruct ConvertsToBoth {
33*67e74705SXin Liprivate:
34*67e74705SXin Li  operator C*() const;
35*67e74705SXin Li
36*67e74705SXin Lipublic:
37*67e74705SXin Li  operator B*() const;
38*67e74705SXin Li};
39*67e74705SXin Li
40*67e74705SXin Livoid test_f1(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) {
41*67e74705SXin Li  f1(toB);
42*67e74705SXin Li  f1(toC);
43*67e74705SXin Li  f1(toBoth);
44*67e74705SXin Li};
45*67e74705SXin Li
46*67e74705SXin Li// A conversion to an a non-id object pointer type is better than a
47*67e74705SXin Li// conversion to 'id'.
48*67e74705SXin Liint &f2(A*);
49*67e74705SXin Lifloat &f2(id);
50*67e74705SXin Li
51*67e74705SXin Livoid test_f2(B *b) {
52*67e74705SXin Li  int &ir = f2(b);
53*67e74705SXin Li}
54*67e74705SXin Li
55*67e74705SXin Li// A conversion to an a non-Class object pointer type is better than a
56*67e74705SXin Li// conversion to 'Class'.
57*67e74705SXin Liint &f3(A*);
58*67e74705SXin Lifloat &f3(Class);
59*67e74705SXin Li
60*67e74705SXin Livoid test_f3(B *b) {
61*67e74705SXin Li  int &ir = f3(b);
62*67e74705SXin Li}
63*67e74705SXin Li
64*67e74705SXin Li// When both conversions convert to 'id' or 'Class', pick the most
65*67e74705SXin Li// specific type to convert from.
66*67e74705SXin Livoid f4(id);
67*67e74705SXin Li
68*67e74705SXin Livoid test_f4(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) {
69*67e74705SXin Li  f4(toB);
70*67e74705SXin Li  f4(toC);
71*67e74705SXin Li  f4(toBoth);
72*67e74705SXin Li}
73*67e74705SXin Li
74*67e74705SXin Livoid f5(id<P1>);
75*67e74705SXin Li
76*67e74705SXin Livoid test_f5(ConvertsTo<B*> toB, ConvertsTo<C*> toC, ConvertsToBoth toBoth) {
77*67e74705SXin Li  f5(toB);
78*67e74705SXin Li  f5(toC);
79*67e74705SXin Li  f5(toBoth);
80*67e74705SXin Li}
81*67e74705SXin Li
82*67e74705SXin Li
83*67e74705SXin Li// A conversion to an a non-id object pointer type is better than a
84*67e74705SXin Li// conversion to qualified 'id'.
85*67e74705SXin Liint &f6(A*);
86*67e74705SXin Lifloat &f6(id<P1>);
87*67e74705SXin Li
88*67e74705SXin Livoid test_f6(B *b) {
89*67e74705SXin Li  int &ir = f6(b);
90*67e74705SXin Li}
91