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>
+
+       * 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.
 
                 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");
 
    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));
 
          || 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.
 
 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);