This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC] [patch] 'p->x' vs. 'p.x' and 'print object on'
- From: ppluzhnikov at google dot com (Paul Pluzhnikov)
- To: gdb-patches at sourceware dot org
- Date: Thu, 17 Jul 2008 14:48:39 -0700 (PDT)
- Subject: [RFC] [patch] 'p->x' vs. 'p.x' and 'print object on'
Greetings,
Long time GDB users are somewhat used to 'p->x' and 'p.x' meaning
the same thing. But, as test case below demonstrates, they don't
mean the same thing when 'set print object on' is in effect.
I believe it is desirable to make the behavior consistent -- either
always accept 'p.x' when 'p->x' was meant, or always insist on
correct form (which is what VisualStudio does).
Attached patch fixes the problem for field access (but not for
mem-function access -- that goes through different path), and
eliminates some redundant code.
Comments?
Test case demonstrating the problem:
--- cut ---
struct Foo {
int x;
Foo() : x(1) { }
virtual ~Foo() { }
};
struct Bar : public Foo {
Bar() : y(2), z(3) { }
int y, z;
};
int fn(Foo *f)
{
return f->x;
}
int main()
{
Bar b;
return fn(&b);
}
--- cut ---
(gdb) b fn
Breakpoint 1 at 0x4002e0: file print-obj.cc, line 14.
(gdb) r
Breakpoint 1, fn (f=0x7fffffffe690) at print-obj.cc:14
14 return f->x;
(gdb) p f
$1 = (Foo *) 0x7fffffffe690
(gdb) set print object on
(gdb) p f
$2 = (Bar *) 0x7fffffffe690
(gdb) p f->z # works
$3 = 3
(gdb) p f.z # doesn't work -- bug in gdb
There is no member or method named z.
# For members of 'Foo' it works either way:
(gdb) p f->x
$4 = 1
(gdb) p f.x
$5 = 1
Thanks,
--
Paul Pluzhnikov
2008-07-17 Paul Pluzhnikov <ppluzhnikov@google.com>
* eval.c (evaluate_subexp_standard): Treat 'p.x' and 'p->x' the same.
Index: eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.85
diff -u -p -u -r1.85 eval.c
--- eval.c 6 Jun 2008 20:58:08 -0000 1.85
+++ eval.c 17 Jul 2008 21:32:49 -0000
@@ -1374,23 +1374,6 @@ evaluate_subexp_standard (struct type *e
return value_literal_complex (arg1, arg2, builtin_type_f_complex_s16);
case STRUCTOP_STRUCT:
- tem = longest_to_int (exp->elts[pc + 1].longconst);
- (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
- arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- if (noside == EVAL_SKIP)
- goto nosideret;
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- return value_zero (lookup_struct_elt_type (value_type (arg1),
- &exp->elts[pc + 2].string,
- 0),
- lval_memory);
- else
- {
- struct value *temp = arg1;
- return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
- NULL, "structure");
- }
-
case STRUCTOP_PTR:
tem = longest_to_int (exp->elts[pc + 1].longconst);
(*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
@@ -1430,8 +1413,10 @@ evaluate_subexp_standard (struct type *e
else
{
struct value *temp = arg1;
+ char *const name =
+ (op == STRUCTOP_STRUCT) ? "structure" : "structure pointer";
return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
- NULL, "structure pointer");
+ NULL, name);
}
case STRUCTOP_MEMBER: