public inbox for gdb-testers@sourceware.org
help / color / mirror / Atom feed
From: gdb-buildbot@sergiodj.net
To: gdb-testers@sourceware.org
Subject: [binutils-gdb] gdb: fix overload resolution for see-through references
Date: Fri, 06 Dec 2019 07:54:00 -0000	[thread overview]
Message-ID: <06acc08f0aa81d0053e9a60bc3bdc1ea3321962e@gdb-build> (raw)

*** TEST RESULTS FOR COMMIT 06acc08f0aa81d0053e9a60bc3bdc1ea3321962e ***

commit 06acc08f0aa81d0053e9a60bc3bdc1ea3321962e
Author:     Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
AuthorDate: Tue Nov 12 15:12:43 2019 +0100
Commit:     Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
CommitDate: Fri Dec 6 08:01:18 2019 +0100

    gdb: fix overload resolution for see-through references
    
    The overload resolution mechanism assigns badness values to the
    necessary conversions to be made on types to pick a champion.  A
    badness value consists of a "rank" that scores the conversion and a
    "subrank" to differentiate conversions of the same kind.
    
    An auxiliary function, 'sum_ranks', is used for adding two badness
    values.  In all of its uses, except two, 'sum_ranks' is used for
    populating the subrank of a badness value.  The two exceptions are in
    'rank_one_type':
    
    ~~~
      /* See through references, since we can almost make non-references
         references.  */
    
      if (TYPE_IS_REFERENCE (arg))
        return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
                           REFERENCE_CONVERSION_BADNESS));
      if (TYPE_IS_REFERENCE (parm))
        return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
                           REFERENCE_CONVERSION_BADNESS));
    ~~~
    
    Here, the result of a recursive call is combined with
    REFERENCE_CONVERSION_BADNESS.  This leads to the problem of
    over-punishment by combining two ranks.  Consider this:
    
        void an_overloaded_function (const foo &);
        void an_overloaded_function (const foo &&);
        ...
        foo arg;
        an_overloaded_function(arg);
    
    When ranking 'an_overloaded_function (const foo &)', the badness
    values REFERENCE_CONVERSION_BADNESS and CV_CONVERSION_BADNESS are
    combined, whereas 'rank_one_type' assigns only the
    REFERENCE_CONVERSION_BADNESS value to 'an_overloaded_function (const
    foo &&)' (there is a different execution flow for that).  This yields
    in GDB picking the latter function as the overload champion instead of
    the former.
    
    In fact, the 'rank_one_type' function should have given
    'an_overloaded_function (const foo &)' the CV_CONVERSION_BADNESS
    value, with the see-through referencing increasing the subrank a
    little bit.  This can be achieved by introducing a new badness value,
    REFERENCE_SEE_THROUGH_BADNESS, which bumps up the subrank only, and
    using it in the two "exceptional" cases of 'sum_ranks'.
    
    gdb/ChangeLog:
    2019-12-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
    
            * gdbtypes.h: Define the REFERENCE_SEE_THROUGH_BADNESS value.
            * gdbtypes.c (rank_one_type): Use REFERENCE_SEE_THROUGH_BADNESS
            for ranking see-through reference cases.
    
    gdb/testsuite/ChangeLog:
    2019-12-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
    
            * gdb.cp/rvalue-ref-overload.cc: Add a case that involves both
            CV and reference conversion for overload resolution.
            * gdb.cp/rvalue-ref-overload.exp: Test it.
    
    Change-Id: I39ae6505ab85ad0bd21915368c82540ceeb3aae9

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 7646214ca8..2d6071271a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2019-12-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+	* gdbtypes.h: Define the REFERENCE_SEE_THROUGH_BADNESS value.
+	* gdbtypes.c (rank_one_type): Use REFERENCE_SEE_THROUGH_BADNESS
+	for ranking see-through reference cases.
+
 2019-12-06  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
 	* stack.c (faas_command): Check a command is provided.
 	* thread.c (taas_command, tfaas_command): Likewise.
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 4854f49e48..e226cb7f94 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -60,6 +60,7 @@ 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 REFERENCE_SEE_THROUGH_BADNESS = {0,1};
 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};
@@ -4338,10 +4339,10 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
 
   if (TYPE_IS_REFERENCE (arg))
     return (sum_ranks (rank_one_type (parm, TYPE_TARGET_TYPE (arg), NULL),
-                       REFERENCE_CONVERSION_BADNESS));
+                       REFERENCE_SEE_THROUGH_BADNESS));
   if (TYPE_IS_REFERENCE (parm))
     return (sum_ranks (rank_one_type (TYPE_TARGET_TYPE (parm), arg, NULL),
-                       REFERENCE_CONVERSION_BADNESS));
+                       REFERENCE_SEE_THROUGH_BADNESS));
   if (overload_debug)
   /* Debugging only.  */
     fprintf_filtered (gdb_stderr, 
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index 0dd7333371..a1d95e09de 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -2105,6 +2105,7 @@ extern const struct rank BASE_CONVERSION_BADNESS;
 /* * Badness of converting from non-reference to reference.  Subrank
    is the type of reference conversion being done.  */
 extern const struct rank REFERENCE_CONVERSION_BADNESS;
+extern const struct rank REFERENCE_SEE_THROUGH_BADNESS;
 /* * Conversion to rvalue reference.  */
 #define REFERENCE_CONVERSION_RVALUE 1
 /* * Conversion to const lvalue reference.  */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 79b124b819..adbbd9c9d8 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2019-12-06  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+	* gdb.cp/rvalue-ref-overload.cc: Add a case that involves both
+	CV and reference conversion for overload resolution.
+	* gdb.cp/rvalue-ref-overload.exp: Test it.
+
 2019-12-06  Philippe Waroquiers  <philippe.waroquiers@skynet.be>
 
 	* gdb.threads/pthreads.exp: Test taas and tfaas without command.
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc b/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
index fa6cab03b0..e3111d528b 100644
--- a/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
@@ -35,6 +35,8 @@ public:
 
   int overload1arg (foo_lval_ref);
   int overload1arg (foo_rval_ref);
+  int overloadConst (const foo &);
+  int overloadConst (const foo &&);
 };
 
 void
@@ -71,6 +73,11 @@ main ()
   // result = 1 + 2 + 3 + 3 = 9
   int result = f (i) + f (ci) + f (0) + f (std::move (i));
 
+  /* Overload resolution below requires both a CV-conversion
+     and reference conversion.  */
+  int test_const // = 3
+    = foo_rr_instance1.overloadConst (arg);
+
   marker1 (); // marker1-returns-here
   return result;
 }
@@ -84,3 +91,5 @@ foo::~foo ()                       {}
 
 int foo::overload1arg (foo_lval_ref arg)           { return 1; }
 int foo::overload1arg (foo_rval_ref arg)           { return 2; }
+int foo::overloadConst (const foo &arg)            { return 3; }
+int foo::overloadConst (const foo &&arg)           { return 4; }
diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
index 61f81b4559..693c7cad20 100644
--- a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
+++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp
@@ -49,6 +49,8 @@ cp_test_ptype_class "foo_rr_instance1" "" "class" "foo" \
 	{ method public "~foo();" }
 	{ method public "int overload1arg(foo_lval_ref);" }
 	{ method public "int overload1arg(foo_rval_ref);" }
+	{ method public "int overloadConst(const foo &);" }
+	{ method public "int overloadConst(const foo &&);" }
     }
 
 gdb_test "print foo_rr_instance1.overload1arg(arg)" \
@@ -59,6 +61,8 @@ gdb_test "print foo_rr_instance1.overload1arg(static_cast<foo&&>(arg))" \
     "\\$\[0-9\]+ = 2" \
     "print call overloaded func foo && arg"
 
+gdb_test "print foo_rr_instance1.overloadConst(arg)" "3"
+
 # Test lvalue vs rvalue function overloads
 gdb_test "print f (i)" "= 1" "lvalue reference overload"
 


             reply	other threads:[~2019-12-06  7:45 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-06  7:54 gdb-buildbot [this message]
2019-12-06  7:45 ` Failures on Ubuntu-Aarch64-m64, branch master gdb-buildbot
2019-12-06  7:58 ` Failures on Fedora-i686, " gdb-buildbot
2019-12-06  8:06 ` Failures on Fedora-x86_64-m64, " gdb-buildbot
2019-12-06  8:12 ` Failures on Fedora-x86_64-native-extended-gdbserver-m32, " gdb-buildbot
2019-12-06  8:33 ` Failures on Fedora-x86_64-native-extended-gdbserver-m64, " gdb-buildbot
2019-12-06  8:48 ` Failures on Fedora-x86_64-cc-with-index, " gdb-buildbot
2019-12-06  9:05 ` Failures on Ubuntu-Aarch64-native-gdbserver-m64, " gdb-buildbot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=06acc08f0aa81d0053e9a60bc3bdc1ea3321962e@gdb-build \
    --to=gdb-buildbot@sergiodj.net \
    --cc=gdb-testers@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).