forked from Imagelibrary/binutils-gdb
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>
81 lines
1.6 KiB
C++
81 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;
|
|
}
|