diff options
author | Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> | 2019-12-09 17:07:47 +0100 |
---|---|---|
committer | Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> | 2019-12-09 18:27:51 +0100 |
commit | 330f1d3825daa0d9e8d6c54f4fcf6fa5800e5664 (patch) | |
tree | af9082e08796d7fc0de30d257f67d91a30f6da49 /gdb | |
parent | b43315e206362a09ae70da71a6631bb5e2770554 (diff) | |
download | gdb-330f1d3825daa0d9e8d6c54f4fcf6fa5800e5664.zip gdb-330f1d3825daa0d9e8d6c54f4fcf6fa5800e5664.tar.gz gdb-330f1d3825daa0d9e8d6c54f4fcf6fa5800e5664.tar.bz2 |
gdb: rank an lvalue argument incompatible for an rvalue parameter
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
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 7 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/rvalue-ref-overload.cc | 12 | ||||
-rw-r--r-- | gdb/testsuite/gdb.cp/rvalue-ref-overload.exp | 4 |
5 files changed, 30 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9709d0d..329080e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 508628a..0896f71 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -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; } } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index bfd686d..123344f 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -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 diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc b/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc index e3111d5..30634a9 100644 --- a/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc +++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.cc @@ -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; } diff --git a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp index e92e901..cac3d4b 100644 --- a/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp +++ b/gdb/testsuite/gdb.cp/rvalue-ref-overload.exp @@ -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" |