This is the mail archive of the
gdb-cvs@sourceware.org
mailing list for the GDB project.
[binutils-gdb] gdb: Forward VALUE_LVAL when avoiding side effects for STRUCTOP_PTR
- From: Andrew Burgess <aburgess at sourceware dot org>
- To: gdb-cvs at sourceware dot org
- Date: 27 May 2016 12:31:50 -0000
- Subject: [binutils-gdb] gdb: Forward VALUE_LVAL when avoiding side effects for STRUCTOP_PTR
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ac775bf4d35b7a2d5715e0ccf3d648d4670213fd
commit ac775bf4d35b7a2d5715e0ccf3d648d4670213fd
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Tue May 24 16:17:52 2016 +0100
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.
Diff:
---
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 6609f9c..6884c2d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2016-05-27 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * 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 <tom@tromey.com>
* python/py-value.c (value_object_as_number): Use correct spelling
diff --git a/gdb/eval.c b/gdb/eval.c
index 3f8ca66..de1c663 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 6dc4492..cac628d 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-05-27 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * gdb.base/whatis.c: Extend the test case.
+ * gdb.base/whatis.exp: Add additional tests.
+
2016-05-25 Bernhard Heckel <bernhard.heckel@intel.com>
* gdb.fortran/type.f90: Add pointer variable.
diff --git a/gdb/testsuite/gdb.base/whatis.c b/gdb/testsuite/gdb.base/whatis.c
index d60afa2..e5cfa51 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 93a4d44..0cdcf5b 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.