diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a679110dbeaeddcab7756b27670d76c5d48e3a07..d9b7c607cbb4c1ff22c95ceb3c591f2a868ec32c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,12 @@
+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.
+
 2010-02-11  Pedro Alves  <pedro@codesourcery.com>
 
 	* tracepoint.c (tfile_open): Remove spurious discard_cleanups.
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index eb532384ca660ae2a71edd98dbdd3ab3f55ed5c5..75aa7ca62b2bfe3a14c334695949298babc5667d 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -1885,11 +1885,35 @@ gen_expr_binop_rest (struct expression *exp,
 		 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");
diff --git a/gdb/valarith.c b/gdb/valarith.c
index c87bc6f255e55cbf44f45d0a716d8e74360f98f7..9f91f4e0f0e8bbc1745d41b08325f6a4283b23c0 100644
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -263,17 +263,17 @@ value_bitstring_subscript (struct type *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, struct value *arg1, struct value *arg2
 	  || 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.
diff --git a/gdb/value.h b/gdb/value.h
index 43b8c3bc0e5e5c62dc0f1389b65f1489be21ad36..1f2086e93177ba0048b5fb461de212a411b540fb 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -590,6 +590,10 @@ extern struct value *value_x_unop (struct value *arg1, enum exp_opcode op,
 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);