Test case for unimplemented overload cases. 2010-10-05 Sami Wagiaalla * gdb.cp/oranking.exp: New test. * gdb.cp/oranking.cc: New test program. diff --git a/gdb/testsuite/gdb.cp/oranking.cc b/gdb/testsuite/gdb.cp/oranking.cc new file mode 100644 index 0000000..dc1972a --- /dev/null +++ b/gdb/testsuite/gdb.cp/oranking.cc @@ -0,0 +1,207 @@ + +/* 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 int foo12(T) { return 41; } + int foo12(int) { return 42; } +int test12 (){ + return foo12(1); //42 +} + +// - F1 is a more specialized template instance +template int foo13(T) { return 43; } +template 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 +} diff --git a/gdb/testsuite/gdb.cp/oranking.exp b/gdb/testsuite/gdb.cp/oranking.exp new file mode 100644 index 0000000..abe8252 --- /dev/null +++ b/gdb/testsuite/gdb.cp/oranking.exp @@ -0,0 +1,100 @@ +# 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 . + +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" + + +