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