This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Don't allow subscripting non-subscriptable types, in agent expressions
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Thu, 11 Feb 2010 21:47:14 +0000
- Subject: Don't allow subscripting non-subscriptable types, in agent expressions
I've applied the patch below, to make the agent expression
builder refuse subscripting non-subscriptable types. Agent
expressions can't do function calls either.
BP:
std::vector<int> v;
int main () {}
(gdb) maint agent v[0]
../../src/gdb/ax-gdb.c:968: internal-error: gen_ptradd: Assertion `pointer_type (value1->type)' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n)
(gdb) maint agent (*(int*)main)[0]
../../src/gdb/ax-gdb.c:968: internal-error: gen_ptradd: Assertion `pointer_type (value1->type)' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n)
AP:
(gdb) maint agent v[0]
cannot subscript requested type: cannot call user defined functions
(gdb) maint agent (*(int*)main)[0]
cannot subscript something of type `int'
--
Pedro Alves
2010-02-11 Pedro Alves <pedro@codesourcery.com>
* ax-gdb.c (gen_exp_binop_rest) [BINOP_SUBSCRIPT]: Error out on
non-subscriptable types.
* valarith.c (binop_types_user_defined_p): New, abstracted out
from ...
(binop_user_defined_p): ... this.
* value.h (binop_types_user_defined_p): Declare.
---
gdb/ax-gdb.c | 34 +++++++++++++++++++++++++++++-----
gdb/valarith.c | 21 +++++++++++++++++----
gdb/value.h | 4 ++++
3 files changed, 50 insertions(+), 9 deletions(-)
Index: src/gdb/ax-gdb.c
===================================================================
--- src.orig/gdb/ax-gdb.c 2010-02-11 18:19:12.000000000 +0000
+++ src/gdb/ax-gdb.c 2010-02-11 21:26:27.000000000 +0000
@@ -1885,11 +1885,35 @@ gen_expr_binop_rest (struct expression *
aop_rem_signed, aop_rem_unsigned, 1, "remainder");
break;
case BINOP_SUBSCRIPT:
- gen_ptradd (ax, value, value1, value2);
- if (!pointer_type (value->type))
- error (_("Invalid combination of types in array subscripting."));
- gen_deref (ax, value);
- break;
+ {
+ struct type *type;
+
+ if (binop_types_user_defined_p (op, value1->type, value2->type))
+ {
+ error (_("\
+cannot subscript requested type: cannot call user defined functions"));
+ }
+ else
+ {
+ /* If the user attempts to subscript something that is not
+ an array or pointer type (like a plain int variable for
+ example), then report this as an error. */
+ type = check_typedef (value1->type);
+ if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_PTR)
+ {
+ if (TYPE_NAME (type))
+ error (_("cannot subscript something of type `%s'"),
+ TYPE_NAME (type));
+ else
+ error (_("cannot subscript requested type"));
+ }
+ }
+
+ gen_ptradd (ax, value, value1, value2);
+ gen_deref (ax, value);
+ break;
+ }
case BINOP_BITWISE_AND:
gen_binop (ax, value, value1, value2,
aop_bit_and, aop_bit_and, 0, "bitwise and");
Index: src/gdb/valarith.c
===================================================================
--- src.orig/gdb/valarith.c 2010-02-11 18:09:06.000000000 +0000
+++ src/gdb/valarith.c 2010-02-11 21:13:18.000000000 +0000
@@ -263,17 +263,17 @@ value_bitstring_subscript (struct type *
For now, we do not overload the `=' operator. */
int
-binop_user_defined_p (enum exp_opcode op, struct value *arg1, struct value *arg2)
+binop_types_user_defined_p (enum exp_opcode op,
+ struct type *type1, struct type *type2)
{
- struct type *type1, *type2;
if (op == BINOP_ASSIGN || op == BINOP_CONCAT)
return 0;
- type1 = check_typedef (value_type (arg1));
+ type1 = check_typedef (type1);
if (TYPE_CODE (type1) == TYPE_CODE_REF)
type1 = check_typedef (TYPE_TARGET_TYPE (type1));
- type2 = check_typedef (value_type (arg2));
+ type2 = check_typedef (type1);
if (TYPE_CODE (type2) == TYPE_CODE_REF)
type2 = check_typedef (TYPE_TARGET_TYPE (type2));
@@ -281,6 +281,19 @@ binop_user_defined_p (enum exp_opcode op
|| TYPE_CODE (type2) == TYPE_CODE_STRUCT);
}
+/* Check to see if either argument is a structure, or a reference to
+ one. This is called so we know whether to go ahead with the normal
+ binop or look for a user defined function instead.
+
+ For now, we do not overload the `=' operator. */
+
+int
+binop_user_defined_p (enum exp_opcode op,
+ struct value *arg1, struct value *arg2)
+{
+ return binop_types_user_defined_p (op, value_type (arg1), value_type (arg2));
+}
+
/* Check to see if argument is a structure. This is called so
we know whether to go ahead with the normal unop or look for a
user defined function instead.
Index: src/gdb/value.h
===================================================================
--- src.orig/gdb/value.h 2010-02-11 18:09:06.000000000 +0000
+++ src/gdb/value.h 2010-02-11 21:13:18.000000000 +0000
@@ -590,6 +590,10 @@ extern struct value *value_x_unop (struc
extern struct value *value_fn_field (struct value **arg1p, struct fn_field *f,
int j, struct type *type, int offset);
+extern int binop_types_user_defined_p (enum exp_opcode op,
+ struct type *type1,
+ struct type *type2);
+
extern int binop_user_defined_p (enum exp_opcode op, struct value *arg1,
struct value *arg2);