This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [RFA] Fix c++/14819 (implicit this)
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Keith Seitz <keiths at redhat dot com>
- Cc: "gdb-patches at sourceware dot org ml" <gdb-patches at sourceware dot org>
- Date: Wed, 6 Nov 2013 14:44:51 +0100
- Subject: Re: [RFA] Fix c++/14819 (implicit this)
- Authentication-results: sourceware.org; auth=none
- References: <52795E6A dot 2050506 at redhat dot com>
Hi Keith,
while the solution seems pretty tricky (some more comments what each line does
would be helpful) it does not work for 'p B::i' and 'p C::i'. But these could
be fixed I guess, I did not try to do so.
------------------------------------------------------------------------------
class A {
public:
int i;
A(int i_):i(i_) {}
};
class B:public A { public: B():A(1) {} };
class C:public A { public: C():A(2) {} };
class D:public B,public C {
public:
int f() {
return B::i + C::i;
// return i; // error: reference to ‘i’ is ambiguous
// return A::i; // error: ‘A’ is an ambiguous base of ‘D’
}
};
D d;
int main() { return d.f(); }
------------------------------------------------------------------------------
(gdb) p B::i
base class 'A' is ambiguous in type 'D'
- this is bug
(gdb) p C::i
base class 'A' is ambiguous in type 'D'
- this is bug
(gdb) p A::i
base class 'A' is ambiguous in type 'D'
- this is correct
(gdb) p i
$1 = 2
- this seems already filed as:
ambiguous using reference is not error
http://sourceware.org/bugzilla/show_bug.cgi?id=11540
------------------------------------------------------------------------------
On Tue, 05 Nov 2013 22:08:58 +0100, Keith Seitz wrote:
> --- a/gdb/valops.c
> +++ b/gdb/valops.c
> @@ -3131,7 +3131,32 @@ value_struct_elt_for_reference (struct type *domain, int offset,
> else if (noside == EVAL_AVOID_SIDE_EFFECTS)
> return allocate_value (TYPE_FIELD_TYPE (t, i));
> else
> - error (_("Cannot reference non-static field \"%s\""), name);
> + {
> + /* Try to evaluate NAME as a qualified name with implicit
> + this pointer. In this case, attempt to return the
> + equivalent to `this->*(&TYPE::NAME)'. */
> + v = value_of_this_silent (current_language);
> + if (v != NULL)
> + {
> + struct value *ptr;
> + long mem_offset;
LONGEST, it is returned by value_as_long.
> + struct type *type, *tmp;
> +
> + ptr = value_aggregate_elt (t, name, NULL, 1, noside);
I cannot reproduce it but I find it a bit fragile, value_aggregate_elt can
return NULL (although it probably would not get here in such case).
At least gdb_assert would be good.
> + type = check_typedef (value_type (ptr));
> + gdb_assert (type != NULL
> + && TYPE_CODE (type) == TYPE_CODE_MEMBERPTR);
> + tmp = lookup_pointer_type (TYPE_DOMAIN_TYPE (type));
> + v = value_cast_pointers (tmp, v, 1);
> + mem_offset = value_as_long (ptr);
> + tmp = lookup_pointer_type (TYPE_TARGET_TYPE (type));
> + result = value_from_pointer (tmp,
> + value_as_long (v) + mem_offset);
> + return value_ind (result);
> + }
> +
> + error (_("Cannot reference non-static field \"%s\""), name);
> + }
> }
> }
Thanks,
Jan