diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 106 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 13 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/oranking.cc | 22 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/oranking.exp | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/rvalue-ref-overload.exp | 1 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/rvalue-ref-params.exp | 1 |
8 files changed, 119 insertions, 57 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9179abf..88b44f9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2017-04-27 Keith Seitz <keiths@redhat.com> + + * gdbtypes.c (LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS) + DIFFERENT_REFERENCE_TYPE_BADNESS): Remove. + (CV_CONVERSION_BADNESS): Define. + (rank_one_type): Remove overly restrictive rvalue reference + rank checks. + Add cv-qualifier checks and subranks for type equality. + * gdbtypes.h (REFERENCE_CONVERSION_RVALUE, + REFERENCE_CONVERSION_CONST_LVALUE, CV_CONVERSION_BADNESS, + CV_CONVERSION_CONST, CV_CONVERSION_VOLATILE): Declare. + 2017-04-27 Simon Marchi <simon.marchi@ericsson.com> * python/py-inferior.c (inferior_to_inferior_object): Increment reference diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index dd3992c..c9a9b3d 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -51,6 +51,7 @@ const struct rank EXACT_MATCH_BADNESS = {0,0}; const struct rank INTEGER_PROMOTION_BADNESS = {1,0}; const struct rank FLOAT_PROMOTION_BADNESS = {1,0}; const struct rank BASE_PTR_CONVERSION_BADNESS = {1,0}; +const struct rank CV_CONVERSION_BADNESS = {1, 0}; const struct rank INTEGER_CONVERSION_BADNESS = {2,0}; const struct rank FLOAT_CONVERSION_BADNESS = {2,0}; const struct rank INT_FLOAT_CONVERSION_BADNESS = {2,0}; @@ -58,8 +59,6 @@ const struct rank VOID_PTR_CONVERSION_BADNESS = {2,0}; const struct rank BOOL_CONVERSION_BADNESS = {3,0}; const struct rank BASE_CONVERSION_BADNESS = {2,0}; const struct rank REFERENCE_CONVERSION_BADNESS = {2,0}; -const struct rank LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS = {5,0}; -const struct rank DIFFERENT_REFERENCE_TYPE_BADNESS = {6,0}; const struct rank NULL_POINTER_CONVERSION_BADNESS = {2,0}; const struct rank NS_POINTER_CONVERSION_BADNESS = {10,0}; const struct rank NS_INTEGER_POINTER_CONVERSION_BADNESS = {3,0}; @@ -3619,57 +3618,51 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value) if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF) arg = check_typedef (arg); - if (value != NULL) + if (TYPE_IS_REFERENCE (parm) && value != NULL) { - /* An rvalue argument cannot be bound to a non-const lvalue - reference parameter... */ - if (VALUE_LVAL (value) == not_lval - && TYPE_CODE (parm) == TYPE_CODE_REF - && !TYPE_CONST (parm->main_type->target_type)) - return INCOMPATIBLE_TYPE_BADNESS; - - /* ... and an lvalue argument cannot be bound to an rvalue - reference parameter. [C++ 13.3.3.1.4p3] */ - if (VALUE_LVAL (value) != not_lval - && TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF) - return INCOMPATIBLE_TYPE_BADNESS; + if (VALUE_LVAL (value) == not_lval) + { + /* Rvalues should preferably bind to rvalue references or const + lvalue references. */ + if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF) + rank.subrank = REFERENCE_CONVERSION_RVALUE; + else if (TYPE_CONST (TYPE_TARGET_TYPE (parm))) + rank.subrank = REFERENCE_CONVERSION_CONST_LVALUE; + else + return INCOMPATIBLE_TYPE_BADNESS; + return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS); + } + else + { + /* Lvalues should prefer lvalue overloads. */ + if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF) + { + rank.subrank = REFERENCE_CONVERSION_RVALUE; + return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS); + } + } } if (types_equal (parm, arg)) - return EXACT_MATCH_BADNESS; - - /* An lvalue reference to a function should get higher priority than an - rvalue reference to a function. */ - - if (value != NULL && TYPE_CODE (arg) == TYPE_CODE_RVALUE_REF - && TYPE_CODE (TYPE_TARGET_TYPE (arg)) == TYPE_CODE_FUNC) - { - return (sum_ranks (rank_one_type (parm, - lookup_pointer_type (TYPE_TARGET_TYPE (arg)), NULL), - DIFFERENT_REFERENCE_TYPE_BADNESS)); - } - - /* If a conversion to one type of reference is an identity conversion, and a - conversion to the second type of reference is a non-identity conversion, - choose the first type. */ - - if (value != NULL && TYPE_IS_REFERENCE (parm) && TYPE_IS_REFERENCE (arg) - && TYPE_CODE (parm) != TYPE_CODE (arg)) { - return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), - TYPE_TARGET_TYPE (arg), NULL), DIFFERENT_REFERENCE_TYPE_BADNESS)); - } + struct type *t1 = parm; + struct type *t2 = arg; - /* An rvalue should be first tried to bind to an rvalue reference, and then to - an lvalue reference. */ + /* For pointers and references, compare target type. */ + if (TYPE_CODE (parm) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (parm)) + { + t1 = TYPE_TARGET_TYPE (parm); + t2 = TYPE_TARGET_TYPE (arg); + } - if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF - && VALUE_LVAL (value) == not_lval) - { - if (TYPE_IS_REFERENCE (arg)) - arg = TYPE_TARGET_TYPE (arg); - return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL), - LVALUE_REFERENCE_TO_RVALUE_BINDING_BADNESS)); + /* Make sure they are CV equal, too. */ + if (TYPE_CONST (t1) != TYPE_CONST (t2)) + rank.subrank |= CV_CONVERSION_CONST; + if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) + rank.subrank |= CV_CONVERSION_VOLATILE; + if (rank.subrank != 0) + return sum_ranks (CV_CONVERSION_BADNESS, rank); + return EXACT_MATCH_BADNESS; } /* See through references, since we can almost make non-references @@ -3711,10 +3704,23 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value) return INCOMPATIBLE_TYPE_BADNESS; case TYPE_CODE_ARRAY: - if (types_equal (TYPE_TARGET_TYPE (parm), - TYPE_TARGET_TYPE (arg))) - return EXACT_MATCH_BADNESS; - return INCOMPATIBLE_TYPE_BADNESS; + { + struct type *t1 = TYPE_TARGET_TYPE (parm); + struct type *t2 = TYPE_TARGET_TYPE (arg); + + if (types_equal (t1, t2)) + { + /* Make sure they are CV equal. */ + if (TYPE_CONST (t1) != TYPE_CONST (t2)) + rank.subrank |= CV_CONVERSION_CONST; + if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) + rank.subrank |= CV_CONVERSION_VOLATILE; + if (rank.subrank != 0) + return sum_ranks (CV_CONVERSION_BADNESS, rank); + return EXACT_MATCH_BADNESS; + } + return INCOMPATIBLE_TYPE_BADNESS; + } case TYPE_CODE_FUNC: return rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL); case TYPE_CODE_INT: diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index f6b4de9..6f896db 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -1891,10 +1891,21 @@ extern const struct rank VOID_PTR_CONVERSION_BADNESS; extern const struct rank BOOL_CONVERSION_BADNESS; /* * Badness of converting derived to base class. */ extern const struct rank BASE_CONVERSION_BADNESS; -/* * Badness of converting from non-reference to reference. */ +/* * Badness of converting from non-reference to reference. Subrank + is the type of reference conversion being done. */ extern const struct rank REFERENCE_CONVERSION_BADNESS; +/* * Conversion to rvalue reference. */ +#define REFERENCE_CONVERSION_RVALUE 1 +/* * Conversion to const lvalue reference. */ +#define REFERENCE_CONVERSION_CONST_LVALUE 2 + /* * Badness of converting integer 0 to NULL pointer. */ extern const struct rank NULL_POINTER_CONVERSION; +/* * Badness of cv-conversion. Subrank is a flag describing the conversions + being done. */ +extern const struct rank CV_CONVERSION_BADNESS; +#define CV_CONVERSION_CONST 1 +#define CV_CONVERSION_VOLATILE 2 /* Non-standard conversions allowed by the debugger */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c4d5b79..a835a40 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2017-04-27 Keith Seitz <keiths@redhat.com> + + * gdb.cp/oranking.cc (test15): New function. + (main): Call test15 and declare additional variables for testing. + * gdb.cp/oranking.exp: Remove kfail status for "p foo4(&a)" and + "p foo101('abc')" tests. + Add tests for cv qualifier overloads. + * gdb.cp/rvalue-ref-overloads.exp: Remove kfail status for + "lvalue reference overload" test. + * gdb.cp/rvalue-ref-params.exp: Remove kfail status for + "print value of f1 on Child&& in f2" test. + 2017-04-19 Pedro Alves <palves@redhat.com> * gdb.threads/threadapply.exp (kill_and_remove_inferior): New diff --git a/gdb/testsuite/gdb.cp/oranking.cc b/gdb/testsuite/gdb.cp/oranking.cc index dc1972a..bd2f51b 100644 --- a/gdb/testsuite/gdb.cp/oranking.cc +++ b/gdb/testsuite/gdb.cp/oranking.cc @@ -147,6 +147,23 @@ int test14 (){ return foo14(e); // 46 } +/* Test cv qualifier overloads. */ +int foo15 (char *arg) { return 47; } +int foo15 (const char *arg) { return 48; } +int foo15 (volatile char *arg) { return 49; } +int foo15 (const volatile char *arg) { return 50; } +static int +test15 () +{ + char *c = 0; + const char *cc = 0; + volatile char *vc = 0; + const volatile char *cvc = 0; + + // 47 + 48 + 49 + 50 = 194 + return foo15 (c) + foo15 (cc) + foo15 (vc) + foo15 (cvc); +} + int main() { B b; foo0(b); @@ -203,5 +220,10 @@ int main() { foo14(e); test14(); + const char *cc = 0; + volatile char *vc = 0; + const volatile char *cvc = 0; + test15 (); + return 0; // end of main } diff --git a/gdb/testsuite/gdb.cp/oranking.exp b/gdb/testsuite/gdb.cp/oranking.exp index 69efb0c..dc7c78b 100644 --- a/gdb/testsuite/gdb.cp/oranking.exp +++ b/gdb/testsuite/gdb.cp/oranking.exp @@ -48,7 +48,6 @@ 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" @@ -71,7 +70,6 @@ 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" @@ -91,5 +89,8 @@ gdb_test "p test14()" "46" setup_kfail "gdb/12096" *-*-* gdb_test "p foo14(e)" "46" - - +gdb_test "p test15 ()" "194" +gdb_test "p foo15 (c)" "47" +gdb_test "p foo15 (cc)" "48" +gdb_test "p foo15 (vc)" "49" +gdb_test "p foo15 (cvc)" "50" diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp index e729209..5cfd34e 100644 --- a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp +++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp @@ -60,7 +60,6 @@ gdb_test "print foo_rr_instance1.overload1arg(static_cast<foo&&>(arg))" \ "print call overloaded func foo && arg" # Test lvalue vs rvalue function overloads -setup_kfail "c++/15372" "*-*-*" gdb_test "print f (i)" "= 1" "lvalue reference overload" gdb_test "print f (ci)" "= 2" "lvalue reference to const overload" diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-params.exp b/gdb/testsuite/gdb.cp/rvalue-ref-params.exp index 303b447..611b592 100644 --- a/gdb/testsuite/gdb.cp/rvalue-ref-params.exp +++ b/gdb/testsuite/gdb.cp/rvalue-ref-params.exp @@ -48,7 +48,6 @@ set t "print value of Child&& in f2" gdb_start_again "marker2 here" $t gdb_test "print C" ".*id = 42.*" $t -setup_kfail "c++/15372" "*-*-*" gdb_test "print f1 (static_cast<Child&&> (C))" ".* = 42.*" \ "print value of f1 on Child&& in f2" |