From ac775bf4d35b7a2d5715e0ccf3d648d4670213fd Mon Sep 17 00:00:00 2001 From: Andrew Burgess Date: Tue, 24 May 2016 16:17:52 +0100 Subject: [PATCH] gdb: Forward VALUE_LVAL when avoiding side effects for STRUCTOP_PTR Assume that we have a C program like this: struct foo_type { int var; } foo; struct foo_type *foo_ptr = &foo; int main () { return foo_ptr->var; } Then GDB should be able to evaluate the following, however, it currently does not: (gdb) start ... (gdb) whatis &(foo_ptr->var) Attempt to take address of value not located in memory. The problem is that in EVAL_AVOID_SIDE_EFFECTS mode, eval.c:evaluate_subexp_standard always returns a not_lval value as the result for a STRUCTOP_PTR operation. As a consequence, the rest of the code believes that one cannot take the address of the returned value. This patch fixes STRUCTOP_PTR handling so that the VALUE_LVAL attribute for the returned value is properly initialized. After this change, the above session becomes: (gdb) start ... (gdb) whatis &(foo_ptr->var) type = int * This commit is largely the same as commit 2520f728b710 (Forward VALUE_LVAL when avoiding side effects for STRUCTOP_STRUCT) but applied to STRUCTOP_PTR rather than STRUCTOP_STRUCT. Both of these commits are building on top of commit ac1ca910d74d (Fixes for PR exp/15364). gdb/ChangeLog: * eval.c (evaluate_subexp_standard): If EVAL_AVOID_SIDE_EFFECTS mode, forward the VALUE_LVAL attribute to the returned value in the STRUCTOP_PTR case. gdb/testsuite/ChangeLog: * gdb.base/whatis.c: Extend the test case. * gdb.base/whatis.exp: Add additional tests. --- gdb/ChangeLog | 6 +++ gdb/eval.c | 2 +- gdb/testsuite/ChangeLog | 5 ++ gdb/testsuite/gdb.base/whatis.c | 8 +-- gdb/testsuite/gdb.base/whatis.exp | 83 +++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 5 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6609f9c7e7..6884c2db3b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2016-05-27 Andrew Burgess + + * eval.c (evaluate_subexp_standard): If EVAL_AVOID_SIDE_EFFECTS + mode, forward the VALUE_LVAL attribute to the returned value in + the STRUCTOP_PTR case. + 2016-05-25 Tom Tromey * python/py-value.c (value_object_as_number): Use correct spelling diff --git a/gdb/eval.c b/gdb/eval.c index 3f8ca662a2..de1c6632e0 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -1917,7 +1917,7 @@ evaluate_subexp_standard (struct type *expect_type, arg3 = value_struct_elt (&arg1, NULL, &exp->elts[pc + 2].string, NULL, "structure pointer"); if (noside == EVAL_AVOID_SIDE_EFFECTS) - arg3 = value_zero (value_type (arg3), not_lval); + arg3 = value_zero (value_type (arg3), VALUE_LVAL (arg3)); return arg3; case STRUCTOP_MEMBER: diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 6dc4492de2..cac628d6cf 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-05-27 Andrew Burgess + + * gdb.base/whatis.c: Extend the test case. + * gdb.base/whatis.exp: Add additional tests. + 2016-05-25 Bernhard Heckel * gdb.fortran/type.f90: Add pointer variable. diff --git a/gdb/testsuite/gdb.base/whatis.c b/gdb/testsuite/gdb.base/whatis.c index d60afa222d..e5cfa51ef2 100644 --- a/gdb/testsuite/gdb.base/whatis.c +++ b/gdb/testsuite/gdb.base/whatis.c @@ -135,7 +135,7 @@ struct t_struct { #endif float v_float_member; double v_double_member; -} v_struct1; +} v_struct1, *v_struct_ptr1; struct { char v_char_member; @@ -147,7 +147,7 @@ struct { #endif float v_float_member; double v_double_member; -} v_struct2; +} v_struct2, *v_struct_ptr2; /**** unions *******/ @@ -161,7 +161,7 @@ union t_union { #endif float v_float_member; double v_double_member; -} v_union; +} v_union, *v_union_ptr; union { char v_char_member; @@ -173,7 +173,7 @@ union { #endif float v_float_member; double v_double_member; -} v_union2; +} v_union2, *v_union_ptr2; /*** Functions returning type ********/ diff --git a/gdb/testsuite/gdb.base/whatis.exp b/gdb/testsuite/gdb.base/whatis.exp index 93a4d440ce..0cdcf5b53d 100644 --- a/gdb/testsuite/gdb.base/whatis.exp +++ b/gdb/testsuite/gdb.base/whatis.exp @@ -294,6 +294,47 @@ gdb_test "whatis v_struct2" \ "type = struct \{\.\.\.\}" \ "whatis unnamed structure" +gdb_test "whatis &v_struct1" \ + "type = struct t_struct \\*" + +gdb_test "whatis &v_struct2" \ + "type = struct {\\.\\.\\.} \\*" + +gdb_test "whatis v_struct_ptr1" \ + "type = struct t_struct \\*" + +gdb_test "whatis v_struct_ptr2" \ + "type = struct {\\.\\.\\.} \\*" + +gdb_test "whatis &v_struct_ptr1" \ + "type = struct t_struct \\*\\*" + +gdb_test "whatis &v_struct_ptr2" \ + "type = struct {\\.\\.\\.} \\*\\*" + +gdb_test "whatis v_struct1.v_char_member" \ + "type = char" + +gdb_test "whatis v_struct2.v_char_member" \ + "type = char" + +gdb_test "whatis v_struct_ptr1->v_char_member" \ + "type = char" + +gdb_test "whatis v_struct_ptr2->v_char_member" \ + "type = char" + +gdb_test "whatis &(v_struct1.v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_struct2.v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_struct_ptr1->v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_struct_ptr2->v_char_member)" \ + "type = char \\*" # test whatis command with union types gdb_test "whatis v_union" \ @@ -308,6 +349,48 @@ gdb_test "whatis v_union2" \ "type = union \{\.\.\.\}" \ "whatis unnamed union" +gdb_test "whatis &v_union" \ + "type = union t_union \\*" + +gdb_test "whatis &v_union2" \ + "type = union {\\.\\.\\.} \\*" + +gdb_test "whatis v_union_ptr" \ + "type = union t_union \\*" + +gdb_test "whatis v_union_ptr2" \ + "type = union {\\.\\.\\.} \\*" + +gdb_test "whatis &v_union_ptr" \ + "type = union t_union \\*\\*" + +gdb_test "whatis &v_union_ptr2" \ + "type = union {\\.\\.\\.} \\*\\*" + +gdb_test "whatis v_union.v_char_member" \ + "type = char" + +gdb_test "whatis v_union2.v_char_member" \ + "type = char" + +gdb_test "whatis v_union_ptr->v_char_member" \ + "type = char" + +gdb_test "whatis v_union_ptr2->v_char_member" \ + "type = char" + +gdb_test "whatis &(v_union.v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_union2.v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_union_ptr->v_char_member)" \ + "type = char \\*" + +gdb_test "whatis &(v_union_ptr2->v_char_member)" \ + "type = char \\*" + # Using stabs we will mark these functions as prototyped. This # is harmless but causes an extra VOID to be printed.