gdb: rank an lvalue argument incompatible for an rvalue parameter
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Mon, 9 Dec 2019 16:07:47 +0000 (17:07 +0100)
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Mon, 9 Dec 2019 17:27:51 +0000 (18:27 +0100)
Passing an lvalue argument to a function that takes an rvalue parameter
is not allowed per C++ rules.  Consider this function:

    int g (int &&x) { return x; }

Calling g as in

    int i = 5;
    int j = g (i);

is illegal.  For instance, GCC 9.2.1 yields

~~~
test.cpp: In function ‘int main()’:
test.cpp:6:14: error: cannot bind rvalue reference of type ‘int&&’ to
lvalue of type ‘int’
    6 |   int j = g (i);
      |              ^
~~~

GDB currently allows this function call:

~~~
(gdb) print g(i)
$1 = 5
~~~

Fix this by ranking an lvalue argument incompatible with an rvalue
parameter.  The behavior after this patch is:

~~~
(gdb) print g(i)
Cannot resolve function g to any overloaded instance
~~~

Tested with GCC 9.2.1.

gdb/ChangeLog:
2019-12-09  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* gdbtypes.c (rank_one_type): Return INCOMPATIBLE_TYPE_BADNESS
when ranking an lvalue argument for an rvalue parameter.

gdb/testsuite/ChangeLog:
2019-12-09  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>

* gdb.cp/rvalue-ref-overload.cc (g): New function that takes
an rvalue parameter.
* gdb.cp/rvalue-ref-overload.exp: Test calling it with an lvalue
parameter.

Change-Id: I4a6dfc7dac63efa1e3b9f8f391e4b736fbdccdc1

gdb/ChangeLog
gdb/gdbtypes.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/rvalue-ref-overload.cc
gdb/testsuite/gdb.cp/rvalue-ref-overload.exp

index 9709d0de33551fcb089229afb48ca853a84207e7..329080e645cbc025f8ad3c2f4d1697188bcd1594 100644 (file)
@@ -1,3 +1,8 @@
+2019-12-09  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * gdbtypes.c (rank_one_type): Return INCOMPATIBLE_TYPE_BADNESS
+       when ranking an lvalue argument for an rvalue parameter.
+
 2019-12-08  Wataru Ashihara  <wataash@wataash.com>
 
        * darwin-nat.c (darwin_nat_target::create_inferior): Fix
index 508628af1f73a99d66b0eec75788c042635432bb..0896f7189fdcdfdd1043ff5e4d6c212a4bd90f89 100644 (file)
@@ -4303,12 +4303,9 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
        }
       else
        {
-         /* Lvalues should prefer lvalue overloads.  */
+         /* It's illegal to pass an lvalue as an rvalue.  */
          if (TYPE_CODE (parm) == TYPE_CODE_RVALUE_REF)
-           {
-             rank.subrank = REFERENCE_CONVERSION_RVALUE;
-             return sum_ranks (rank, REFERENCE_CONVERSION_BADNESS);
-           }
+           return INCOMPATIBLE_TYPE_BADNESS;
        }
     }
 
index bfd686d0d8f0707b7aad51fb123964c5154e183d..123344ffd8e1f6b9f5112a40e01f77e77886883c 100644 (file)
@@ -1,3 +1,10 @@
+2019-12-09  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * gdb.cp/rvalue-ref-overload.cc (g): New function that takes
+       an rvalue parameter.
+       * gdb.cp/rvalue-ref-overload.exp: Test calling it with an lvalue
+       parameter.
+
 2019-12-09  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdb.mi/mi-fortran-modules.exp: Add patterns to skip system
index e3111d528bd623873d5094f60565ecd9750e21f5..30634a9c36c44d333a228c0d578503ebb5740266 100644 (file)
@@ -62,6 +62,12 @@ f (int &&x)
   return 3;
 }
 
+static int
+g (int &&x)
+{
+  return x;
+}
+
 int
 main ()
 {
@@ -78,6 +84,12 @@ main ()
   int test_const // = 3
     = foo_rr_instance1.overloadConst (arg);
 
+  /* The statement below is illegal: cannot bind rvalue reference of
+     type 'int&&' to lvalue of type 'int'.
+
+     result = g (i); */
+  result = g (5); // this is OK
+
   marker1 (); // marker1-returns-here
   return result;
 }
index e92e90139a449ff48695469a762e7cd129668b2b..cac3d4ba5887cabba63375390c6867dc44d15e8d 100644 (file)
@@ -66,3 +66,7 @@ gdb_test "print f (ci)" "2" "lvalue reference to const overload"
 
 setup_kfail "c++/15372" "*-*-*"
 gdb_test "print f (3)" "3" "rvalue reference overload"
+
+gdb_test "print g (i)" \
+    "Cannot resolve function g to any overloaded instance" \
+    "passing lvalue arg to rvalue parameter"