binutils-gdb/gdb/testsuite/gdb.cp/ref-params.cc
Hannes Domani d391f3721e Fix casting in-memory values of primitive types to const reference
It's currently not possible to cast an in-memory value of a primitive
type to const reference:
```
(gdb) p Q.id
$1 = 42
(gdb) p (int&)Q.id
$2 = (int &) @0x22fd0c: 42
(gdb) p (const int&)Q.id
Attempt to take address of value not located in memory.
```

And if in a function call an argument needs the same kind of casting,
it also doesn't work:
```
(gdb) l f3
39      int f3(const int &i)
40      {
41        return i;
42      }
(gdb) p f3(Q.id)
Attempt to take address of value not located in memory.
```

It's because when the constness of the type changes in a call to
value_cast, a new not_lval value is allocated, which doesn't exist
in the target memory.

Fixed by ignoring const/volatile/restrict qualifications in
value_cast when comparing cast type to original type, so the new
value will point to the same location as the original value:
```
(gdb) p (int&)i
$2 = (int &) @0x39f72c: 1
(gdb) p (const int&)i
$3 = (const int &) @0x39f72c: 1
(gdb) p f3(Q.id)
$4 = 42
```

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=19423
Approved-By: Tom Tromey <tom@tromey.com>
2024-03-20 18:23:50 +01:00

80 lines
1.6 KiB
C++

/* This test script is part of GDB, the GNU debugger.
Copyright 2006-2024 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Author: Paul N. Hilfinger, AdaCore Inc. */
struct Parent {
Parent (int id0) : id(id0) { }
int id;
};
struct Child : public Parent {
Child (int id0) : Parent(id0) { }
};
int f1(Parent& R)
{
return R.id; /* Set breakpoint marker3 here. */
}
int f2(Child& C)
{
return f1(C); /* Set breakpoint marker2 here. */
}
int f3(const int &i)
{
return i;
}
struct OtherParent {
OtherParent (int other_id0) : other_id(other_id0) { }
int other_id;
};
struct MultiChild : public Parent, OtherParent {
MultiChild (int id0) : Parent(id0), OtherParent(id0 * 2) { }
};
int mf1(OtherParent& R)
{
return R.other_id;
}
int mf2(MultiChild& C)
{
return mf1(C);
}
int main(void)
{
Child Q(42);
Child& QR = Q;
/* Set breakpoint marker1 here. */
f2(Q);
f2(QR);
f3(Q.id);
MultiChild MQ(53);
MultiChild& MQR = MQ;
mf2(MQ); /* Set breakpoint MQ here. */
return 0;
}