Skip to content

Commit 798f480

Browse files
rudnickipiotrlgaver2
authored andcommitted
gdb: handle struct and union types in evaluate_subexp_for_address_base
Suppose a function returns a struct and a method of that struct is called. E.g.: struct S { int a; int get () { return a; } }; S f () { S s; s.a = 42; return s; } ... int z = f().get(); ... GDB is able to evaluate the expression: (gdb) print f().get() $1 = 42 However, type-checking the expression fails: (gdb) ptype f().get() Attempt to take address of value not located in memory. This happens because the `get` function takes an implicit `this` pointer, which in this case is the value returned by `f()`, and GDB wants to get an address for that value, as if passing the implicit this pointer. However, during type-checking, the struct value returned by `f()` is a `not_lval`. A similar issue exists for union types, where methods called on temporary union objects would fail type-checking in the same way. Address the problems by handling `TYPE_CODE_STRUCT` and `TYPE_CODE_UNION` in `evaluate_subexp_for_address_base`. With this change, for struct's method call, we get (gdb) ptype f().get() type = int Add new test cases to file gdb.cp/chained-calls.exp to test this change. Regression-tested in X86-64 Linux.
1 parent e8853e9 commit 798f480

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

gdb/eval.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2566,11 +2566,13 @@ evaluate_subexp_for_address_base (enum noside noside, value *x)
25662566
if (noside == EVAL_AVOID_SIDE_EFFECTS)
25672567
{
25682568
struct type *type = check_typedef (x->type ());
2569+
enum type_code typecode = type->code ();
25692570

25702571
if (TYPE_IS_REFERENCE (type))
25712572
return value::zero (lookup_pointer_type (type->target_type ()),
25722573
not_lval);
2573-
else if (x->lval () == lval_memory || value_must_coerce_to_target (x))
2574+
else if (x->lval () == lval_memory || value_must_coerce_to_target (x)
2575+
|| typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
25742576
return value::zero (lookup_pointer_type (x->type ()), not_lval);
25752577
else
25762578
error (_("Attempt to take address of value not located in memory."));

gdb/testsuite/gdb.cp/chained-calls.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class S
2323

2424
S operator+ (const S &s);
2525

26+
int get ();
27+
2628
int a;
2729
};
2830

@@ -41,6 +43,12 @@ S::operator+ (const S &s)
4143
return res;
4244
}
4345

46+
int
47+
S::get ()
48+
{
49+
return a;
50+
}
51+
4452
S
4553
f (int i)
4654
{
@@ -162,6 +170,8 @@ union U
162170
U (type t);
163171
type get_type ();
164172

173+
int get ();
174+
165175
int a;
166176
char c;
167177
type tp[2];
@@ -190,6 +200,12 @@ U::get_type ()
190200
return tp[TYPE_INDEX];
191201
}
192202

203+
int
204+
U::get ()
205+
{
206+
return a;
207+
}
208+
193209
int
194210
main ()
195211
{
@@ -198,6 +214,7 @@ main ()
198214

199215
B b = makeb ();
200216
C c;
217+
int z = f (42).get ();
201218

202219
return i + getb(b, 0); /* Break here */
203220
}

gdb/testsuite/gdb.cp/chained-calls.exp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,6 @@ gdb_test "p *c" ".* = {a = 5678}" "*c"
4242
gdb_test "p *c + *c" ".* = {a = 11356}" "*c + *c"
4343
gdb_test "p q(*c + *c)" ".* = {a = 11356}" "q(*c + *c)"
4444
gdb_test "p make_int().get_type ()" ".* = INT" "make_int().get_type ()"
45+
gdb_test "p f(42).get()" " = 42" "f().get()"
46+
gdb_test "ptype f(42).get()" "type = int" "ptype f().get()"
47+
gdb_test "ptype make_int().get()" "type = int" "make_int().get()"

0 commit comments

Comments
 (0)