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.
This commit is contained in:
Piotr Rudnicki
2025-05-30 15:21:49 +02:00
parent 7b91a240d6
commit a8f4696286
3 changed files with 23 additions and 1 deletions

View File

@@ -2566,11 +2566,13 @@ evaluate_subexp_for_address_base (enum noside noside, value *x)
if (noside == EVAL_AVOID_SIDE_EFFECTS)
{
struct type *type = check_typedef (x->type ());
enum type_code typecode = type->code ();
if (TYPE_IS_REFERENCE (type))
return value::zero (lookup_pointer_type (type->target_type ()),
not_lval);
else if (x->lval () == lval_memory || value_must_coerce_to_target (x))
else if (x->lval () == lval_memory || value_must_coerce_to_target (x)
|| typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
return value::zero (lookup_pointer_type (x->type ()), not_lval);
else
error (_("Attempt to take address of value not located in memory."));