+2010-10-08 Sami Wagiaalla <swagiaal@redhat.com>
+
+ * gdb.cp/oranking.exp: New test.
+ * gdb.cp/oranking.cc: New test program.
+
2010-10-08 Ken Werner <ken.werner@de.ibm.com>
* gdb.base/gnu_vector.c (ia, ib, fa, fb): New variables.
--- /dev/null
+
+/* 1. A standard covnersion sequence is better than a user-defined sequence
+ which is better than an elipses conversion sequence. */
+
+class A{};
+class B: public A {public: operator int (){ return 1;}};
+
+// standard vs user-defined
+int foo0 (int) { return 10; }
+int foo1 (int) { return 11; } // B -> int : user defined
+int foo1 (A) { return 12; } // B -> A : standard
+int test1 () {
+ B b;
+ return foo1(b); // 12
+}
+
+// user-defined vs ellipsis
+int foo2 (int) { return 13;} // B -> int : user defined
+int foo2 (...) { return 14;} // B -> ... : ellipsis
+int test2(){
+ B b;
+ return foo2(b); // 13
+}
+
+/* 2. Standard Conversion squence S1 is better than standard Conversion
+ S2 if: */
+
+// - S1 has a better rank than S2
+// see overload.exp for more comprehensive testing of this.
+int foo3 (double) { return 21; } // float->double is 'promotion rank'
+int foo3 (int) { return 22; } // float->int is 'conversion rank'
+int test3(){
+ return foo3 (1.0f); // 21
+}
+
+// - S1 and S2 are both 'qualification conversions' but S1 cv-qualification
+// is a subset of S2 cv-qualification.
+int foo4 (const volatile int*) { return 23; }
+int foo4 ( volatile int*) { return 24; }
+int test4 () {
+ volatile int a = 5;
+ return foo4(&a); // 24
+}
+
+// - S1 and S2 have the same rank but:
+// - S2 is a conversion of pointer or memeber-pointer to bool
+int foo5 (bool) { return 25; }
+int foo5 (void*) { return 26; }
+int test5 () {
+ char *a;
+ return foo5(a); // 26
+}
+
+// - Class B publicly extends class A and S1 is a conversion of
+// B* to A* and S2 is a conversion B* to void*
+int foo6 (void*) { return 27; }
+int foo6 (A*) { return 28; }
+int test6 () {
+ B *bp;
+ return foo6(bp); // 28
+}
+
+// - Class C publicly extends Class B which publicly extends
+// class A and S1 is a conversion of C* to B* and S2 is a
+// conversion C* to A*.
+class C: public B {};
+int foo7 (A*) { return 29; }
+int foo7 (B*) { return 210; }
+int test7 () {
+ C *cp;
+ return foo7(cp); // 210
+}
+
+// - Same as above but for references.
+int foo8 (A&) { return 211; }
+int foo8 (B&) { return 212; }
+int test8 () {
+ C c;
+ return foo8(c); // 212
+}
+
+// - Same as above but passing by copy.
+int foo9 (A) { return 213; }
+int foo9 (B) { return 214; }
+int test9 () {
+ C c;
+ return foo9(c); // 212
+}
+
+// - S1 is a conversion of A::* to B::* and S2 is a conversion of
+// A::* to C::8.
+int foo10 (void (C::*)()) { return 215; }
+int foo10 (void (B::*)()) { return 216; }
+int test10 () {
+ void (A::*amp)();
+ return foo10(amp); // 216
+}
+
+// - S1 is a subsequence of S2
+int foo101 (volatile const char*) { return 217; } // array-to-pointer conversion
+ // plus qualification conversion
+int foo101 ( const char*) { return 218; } // array-to-pointer conversion
+
+int test101 () {
+ return foo101("abc"); // 216
+}
+
+/* 3. User defined conversion U1 is better than user defined Conversion U2,
+ if U1 and U2 are using the same conversion function but U1 has a better
+ second standard conversion sequence than U2. */
+class D {public: operator short(){ return 0;}};
+int foo11 (float) { return 31; }
+int foo11 (int) { return 32; }
+int test11 () {
+ D d;
+ return foo11(d); // 32
+}
+
+/* 4. Function Level Ranking.
+ All else being equal some functions are preferred by overload resolution.
+ Function F1 is better than function F2 if: */
+// - F1 is a non-template function and F2 is a template function
+template<class T> int foo12(T) { return 41; }
+ int foo12(int) { return 42; }
+int test12 (){
+ return foo12(1); //42
+}
+
+// - F1 is a more specialized template instance
+template<class T> int foo13(T) { return 43; }
+template<class T> int foo13(T*) { return 44; }
+int test13 (){
+ char *c;
+ return foo13(c); // 44
+}
+
+// - The context is user defined conversion and F1 has
+// a better return type than F2
+class E {
+ public:
+ operator double () {return 45; }
+ operator int () {return 46; }
+};
+int foo14 (int a) {return a;}
+int test14 (){
+ E e;
+ return foo14(e); // 46
+}
+
+int main() {
+ B b;
+ foo0(b);
+ foo1(b);
+ test1();
+
+ foo2(b);
+ test2();
+
+ foo3(1.0f);
+ test3();
+
+ volatile int a;
+ foo4(&a);
+ test4();
+
+ char *c;
+ foo5(c);
+ test5();
+
+ B *bp;
+ foo6(bp);
+ test6();
+
+ C *cp;
+ foo7(cp);
+ test7();
+
+ C co;
+ foo8(co);
+ test8();
+
+ foo9(co);
+ test9();
+
+ void (A::*amp)();
+ foo10(amp);
+ test10();
+
+ foo101("abc");
+ test101();
+
+ D d;
+ foo11(d);
+ test11();
+
+ foo12(1);
+ test12();
+
+ foo13(c);
+ test13();
+
+ E e;
+ foo14(e);
+ test14();
+
+ return 0; // end of main
+}
--- /dev/null
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set testfile oranking
+set srcfile ${testfile}.cc
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug c++}] } {
+ return -1
+}
+
+############################################
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint main"
+ continue
+}
+
+gdb_breakpoint [gdb_get_line_number "end of main"]
+gdb_continue_to_breakpoint "end of main"
+
+# The 'test*' functions are to prove our understanding
+# of the overload resolution performed by the compiler
+# So, they should always pass, and the returned value
+# should match the corresponding call to 'foo*'
+
+setup_kfail "gdb/12096" *-*-*
+gdb_test "p foo0(b)" "10"
+
+gdb_test "p test1()" "12"
+gdb_test "p foo1(b)" "12"
+
+gdb_test "p test2()" "13"
+setup_kfail "gdb/12098" *-*-*
+gdb_test "p foo2(b)" "13"
+
+gdb_test "p test3()" "21"
+gdb_test "p foo3(1.0f)" "21"
+
+gdb_test "p test4()" "24"
+setup_kfail "gdb/12098" *-*-*
+gdb_test "p foo4(&a)" "24"
+
+gdb_test "p test5()" "26"
+setup_kfail "gdb/12098" *-*-*
+gdb_test "p foo5(c)" "26"
+
+gdb_test "p test6()" "28"
+setup_kfail "gdb/10343" *-*-*
+gdb_test "p foo6(bp)" "28"
+
+gdb_test "p test7()" "210"
+setup_kfail "gdb/10343" *-*-*
+gdb_test "p foo7(cp)" "210"
+
+gdb_test "p test8()" "212"
+setup_kfail "gdb/10343" *-*-*
+gdb_test "p foo8(co)" "212"
+
+gdb_test "p test9()" "214"
+setup_kfail "gdb/12098" *-*-*
+gdb_test "p foo9(co)" "214"
+
+gdb_test "p test10()" "216"
+setup_kfail "gdb/12098" *-*-*
+gdb_test "p foo10(amp)" "216"
+
+gdb_test "p test101()" "218"
+setup_kfail "gdb/12098" *-*-*
+gdb_test "p foo101(\"abc\")" "218"
+
+gdb_test "p test11()" "32"
+setup_kfail "gdb/12096" *-*-*
+gdb_test "p foo11(d)" "32"
+
+gdb_test "p test12()" "42"
+# this passes only because gdb does not yet
+# implement template function calling
+gdb_test "p foo12(1)" "42"
+
+gdb_test "p test13()" "44"
+setup_kfail "gdb/12098" *-*-*
+gdb_test "p foo13(c)" "44"
+
+gdb_test "p test14()" "46"
+setup_kfail "gdb/12096" *-*-*
+gdb_test "p foo14(e)" "46"
+
+
+