xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.cp/oranking.cc (revision 99e23f81b2b10aef1a10b03588663e472627bb76)
1 #include <cstdlib>
2 
3 /* Make sure `malloc' is linked into the program.  If we don't, tests
4    in the accompanying expect file may fail:
5 
6    evaluation of this expression requires the program to have a function
7    "malloc".  */
8 
9 void
dummy()10 dummy ()
11 {
12   void *p = malloc (16);
13 
14   free (p);
15 }
16 
17 /* 1. A standard covnersion sequence is better than a user-defined sequence
18       which is better than an elipses conversion sequence.  */
19 
20 class A{};
operator int()21 class B: public A {public: operator int (){ return 1;}};
22 
23 // standard vs user-defined
foo0(int)24 int foo0  (int) { return 10; }
foo1(int)25 int foo1  (int) { return 11; } // B -> int   : user defined
foo1(A)26 int foo1  (A)   { return 12; } // B -> A     : standard
test1()27 int test1 () {
28   B b;
29   return foo1(b); // 12
30 }
31 
32 // user-defined vs ellipsis
foo2(int)33 int foo2 (int) { return 13;} // B -> int   : user defined
foo2(...)34 int foo2 (...) { return 14;} // B -> ...   : ellipsis
test2()35 int test2(){
36   B b;
37   return foo2(b); // 13
38 }
39 
40 /* 2. Standard Conversion squence S1 is better than standard Conversion
41       S2 if:  */
42 
43 //      - S1 has a better rank than S2
44 //        see overload.exp for more comprehensive testing of this.
foo3(double)45 int foo3 (double) { return 21; } // float->double is 'promotion rank'
foo3(int)46 int foo3 (int)    { return 22; } // float->int is 'conversion rank'
test3()47 int test3(){
48   return foo3 (1.0f); // 21
49 }
50 
51 //      - S1 and S2 are both 'qualification conversions' but S1 cv-qualification
52 //        is a subset of S2 cv-qualification.
foo4(const volatile int *)53 int foo4 (const volatile int*) { return 23; }
foo4(volatile int *)54 int foo4 (      volatile int*) { return 24; }
test4()55 int test4 () {
56   volatile int a = 5;
57   return foo4(&a); // 24
58 }
59 
60 //      - S1 and S2 have the same rank but:
61 //        - S2 is a conversion of pointer or memeber-pointer to bool
foo5(bool)62 int foo5 (bool)  { return 25; }
foo5(void *)63 int foo5 (void*) { return 26; }
test5()64 int test5 () {
65   char *a;
66   return foo5(a); // 26
67 }
68 
69 //        - Class B publicly extends class A and S1 is a conversion of
70 //          B* to A* and S2 is a conversion B* to void*
foo6(void *)71 int foo6 (void*) { return 27; }
foo6(A *)72 int foo6 (A*)    { return 28; }
test6()73 int test6 () {
74   B *bp;
75   return foo6(bp); // 28
76 }
77 
78 //        - Class C publicly extends Class B which publicly extends
79 //          class A and S1 is a conversion of C* to B* and S2 is a
80 //          conversion C* to A*.
81 class C: public B {};
foo7(A *)82 int foo7 (A*)    { return 29; }
foo7(B *)83 int foo7 (B*) { return 210; }
test7()84 int test7 () {
85   C *cp;
86   return foo7(cp); // 210
87 }
88 
89 //        - Same as above but for references.
foo8(A &)90 int foo8 (A&) { return 211; }
foo8(B &)91 int foo8 (B&) { return 212; }
test8()92 int test8 () {
93   C c;
94   return foo8(c); // 212
95 }
96 
97 //        - Same as above but passing by copy.
foo9(A)98 int foo9 (A) { return 213; }
foo9(B)99 int foo9 (B) { return 214; }
test9()100 int test9 () {
101   C c;
102   return foo9(c); // 212
103 }
104 
105 //        - S1 is a conversion of A::* to B::* and S2 is a conversion of
106 //          A::* to C::8.
foo10(void (C::*)())107 int foo10 (void (C::*)()) { return 215; }
foo10(void (B::*)())108 int foo10 (void (B::*)()) { return 216; }
test10()109 int test10 () {
110   void (A::*amp)();
111   return foo10(amp); // 216
112 }
113 
114 //      - S1 is a subsequence of S2
foo101(volatile const char *)115 int foo101 (volatile const char*) { return 217; } // array-to-pointer conversion
116                                                  // plus qualification conversion
foo101(const char *)117 int foo101 (         const char*) { return 218; } // array-to-pointer conversion
118 
test101()119 int test101 () {
120   return foo101("abc"); // 216
121 }
122 
123 /* 3. User defined conversion U1 is better than user defined Conversion U2,
124       if U1 and U2 are using the same conversion function but U1 has a better
125       second standard conversion sequence than U2.  */
operator short()126 class D {public: operator short(){ return 0;}};
foo11(float)127 int foo11 (float) { return 31; }
foo11(int)128 int foo11 (int)   { return 32; }
test11()129 int test11 () {
130   D d;
131   return foo11(d); // 32
132 }
133 
134 /* 4. Function Level Ranking.
135       All else being equal some functions are preferred by overload resolution.
136       Function F1 is better than function F2 if: */
137 //    - F1 is a non-template function and F2 is a template function
foo12(T)138 template<class T> int foo12(T)   { return 41; }
foo12(int)139                   int foo12(int) { return 42; }
test12()140 int test12 (){
141   return foo12(1); //42
142 }
143 
144 //    - F1 is a more specialized template instance
foo13(T)145 template<class T> int foo13(T)  { return 43; }
foo13(T *)146 template<class T> int foo13(T*) { return 44; }
test13()147 int test13 (){
148   char *c;
149   return foo13(c); // 44
150 }
151 
152 //    - The context is user defined conversion and F1 has
153 //      a better return type than F2
154 class E {
155   public:
operator double()156     operator double () {return 45; }
operator int()157     operator int    () {return 46; }
158 };
foo14(int a)159 int foo14 (int a) {return a;}
test14()160 int test14 (){
161   E e;
162   return foo14(e); // 46
163 }
164 
165 /* Test cv qualifier overloads.  */
foo15(char * arg)166 int foo15 (char *arg) { return 47; }
foo15(const char * arg)167 int foo15 (const char *arg) { return 48; }
foo15(volatile char * arg)168 int foo15 (volatile char *arg) { return 49; }
foo15(const volatile char * arg)169 int foo15 (const volatile char *arg) { return 50; }
170 static int
test15()171 test15 ()
172 {
173   char *c = 0;
174   const char *cc = 0;
175   volatile char *vc = 0;
176   const volatile char *cvc = 0;
177 
178   // 47 + 48 + 49 + 50 = 194
179   return foo15 (c) + foo15 (cc) + foo15 (vc)  + foo15 (cvc);
180 }
181 
main()182 int main() {
183   dummy ();
184 
185   B b;
186   foo0(b);
187   foo1(b);
188   test1();
189 
190   foo2(b);
191   test2();
192 
193   foo3(1.0f);
194   test3();
195 
196   volatile int a;
197   foo4(&a);
198   test4();
199 
200   char *c;
201   foo5(c);
202   test5();
203 
204   B *bp;
205   foo6(bp);
206   test6();
207 
208   C *cp;
209   foo7(cp);
210   test7();
211 
212   C co;
213   foo8(co);
214   test8();
215 
216   foo9(co);
217   test9();
218 
219   void (A::*amp)();
220   foo10(amp);
221   test10();
222 
223   foo101("abc");
224   test101();
225 
226   D d;
227   foo11(d);
228   test11();
229 
230   foo12(1);
231   test12();
232 
233   foo13(c);
234   test13();
235 
236   E e;
237   foo14(e);
238   test14();
239 
240   const char *cc = 0;
241   volatile char *vc = 0;
242   const volatile char *cvc = 0;
243   test15 ();
244 
245   return 0; // end of main
246 }
247