This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
- From: Artemiy Volkov <artemiyv at acm dot org>
- To: gdb-patches at sourceware dot org
- Cc: palves at redhat dot com, Artemiy Volkov <artemiyv at acm dot org>
- Date: Tue, 19 Jan 2016 21:53:27 +0300
- Subject: [PATCH v2 09/11] [PR gdb/14441] gdb: gdbtypes: add rvalue references to overloading resolution
- Authentication-results: sourceware.org; auth=none
- References: <1450661481-31178-1-git-send-email-artemiyv at acm dot org> <1453229609-20159-1-git-send-email-artemiyv at acm dot org>
This patch introduces changes to rank_one_type() dealing with ranking an rvalue
reference type when selecting a best viable function from a set of candidate
functions. The 3 new added rules for rvalue references are:
1) An rvalue argument cannot be bound to a non-const lvalue reference parameter
and an lvalue argument cannot be bound to an rvalue reference parameter.
[C++11 13.3.3.1.4p3]
2) 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. [C++11 13.3.3.2p3]
3) An rvalue should be first tried to bind to an rvalue reference, and then to
an lvalue reference. [C++11 13.3.3.2p3]
4) An lvalue reference to a function gets higher priority than an rvalue
reference to a function. [C++11 13.3.3.2p3]
./ChangeLog:
2016-01-19 Artemiy Volkov <artemiyv@acm.org>
* gdb/gdbtypes.c (rank_one_type): Implement overloading
resolution rules regarding rvalue references.
---
gdb/gdbtypes.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index fd17d3c..4bb98c9 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -58,6 +58,8 @@ 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};
@@ -3464,6 +3466,20 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
{
struct rank rank = {0,0};
+ /* Disallow an rvalue argument to bind to a non-const lvalue reference
+ parameter and an lvalue argument to bind to an rvalue reference
+ parameter. */
+
+ if ((value != NULL)
+ &&
+ ((TYPE_CODE (parm) == TYPE_CODE_REF
+ && !TYPE_CONST (parm->main_type->target_type)
+ && VALUE_LVAL (value) == not_lval)
+ ||
+ (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF
+ && VALUE_LVAL (value) != not_lval)))
+ return INCOMPATIBLE_TYPE_BADNESS;
+
if (types_equal (parm, arg))
return EXACT_MATCH_BADNESS;
@@ -3473,6 +3489,36 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
arg = check_typedef (arg);
+ /* 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_REFERENCE (parm) && TYPE_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));
+
+ /* An rvalue should be first tried to bind to an rvalue reference, and then to
+ an lvalue reference. */
+
+ if (value != NULL && TYPE_CODE (parm) == TYPE_CODE_REF
+ && VALUE_LVAL (value) == not_lval)
+ {
+ if (TYPE_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));
+ }
+
/* See through references, since we can almost make non-references
references. */
--
2.7.0