Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.230 diff -u -p -r1.230 gdbtypes.c --- gdbtypes.c 23 May 2012 23:45:09 -0000 1.230 +++ gdbtypes.c 1 Jun 2012 19:00:32 -0000 @@ -1987,7 +1987,7 @@ is_integral_type (struct type *t) /* Return true if TYPE is scalar. */ -static int +int is_scalar_type (struct type *type) { CHECK_TYPEDEF (type); @@ -2006,6 +2006,20 @@ is_scalar_type (struct type *type) } } +int +is_compound_type (struct type *type) +{ + enum type_code type_code; + + CHECK_TYPEDEF (type); + + type_code = TYPE_CODE (type); + if (type_code == TYPE_CODE_STRUCT || type_code == TYPE_CODE_UNION) + return 1; + else + return 0; +} + /* Return true if T is scalar, or a composite type which in practice has the memory layout of a scalar type. E.g., an array or struct with only one scalar element inside it, or a union with only scalar elements. */ Index: gdbtypes.h =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.h,v retrieving revision 1.165 diff -u -p -r1.165 gdbtypes.h --- gdbtypes.h 18 Apr 2012 06:46:46 -0000 1.165 +++ gdbtypes.h 1 Jun 2012 19:00:33 -0000 @@ -1603,8 +1603,12 @@ extern int can_dereference (struct type extern int is_integral_type (struct type *); +extern int is_scalar_type (struct type *); + extern int is_scalar_type_recursive (struct type *); +extern int is_compound_type (struct type *); + extern void maintenance_print_type (char *, int); extern htab_t create_copied_types_hash (struct objfile *objfile); Index: valarith.c =================================================================== RCS file: /cvs/src/src/gdb/valarith.c,v retrieving revision 1.103 diff -u -p -r1.103 valarith.c --- valarith.c 18 May 2012 21:02:50 -0000 1.103 +++ valarith.c 1 Jun 2012 19:00:33 -0000 @@ -397,7 +397,8 @@ value_x_binop (struct value *arg1, struc /* now we know that what we have to do is construct our arg vector and find the right function to call it with. */ - if (TYPE_CODE (check_typedef (value_type (arg1))) != TYPE_CODE_STRUCT) + if (!is_compound_type (check_typedef (value_type (arg1))) + && !is_compound_type (check_typedef (value_type (arg2)))) error (_("Can't do that binary op on that type")); /* FIXME be explicit */ argvec = (struct value **) alloca (sizeof (struct value *) * 4); @@ -1447,24 +1448,27 @@ value_binop (struct value *arg1, struct int t2_is_vec = (TYPE_CODE (type2) == TYPE_CODE_ARRAY && TYPE_VECTOR (type2)); - if (!t1_is_vec && !t2_is_vec) + if (is_scalar_type (type1) && is_scalar_type (type2)) val = scalar_binop (arg1, arg2, op); else if (t1_is_vec && t2_is_vec) val = vector_binop (arg1, arg2, op); - else + else if ((is_scalar_type (type1) && t2_is_vec) + || (is_scalar_type (type2) && t1_is_vec)) { /* Widen the scalar operand to a vector. */ struct value **v = t1_is_vec ? &arg2 : &arg1; struct type *t = t1_is_vec ? type2 : type1; - - if (TYPE_CODE (t) != TYPE_CODE_FLT - && TYPE_CODE (t) != TYPE_CODE_DECFLOAT - && !is_integral_type (t)) - error (_("Argument to operation not a number or boolean.")); + + if (TYPE_CODE (t) == TYPE_CODE_PTR) + error (_("Argument to arithmetic operation not of valid type.")); *v = value_cast (t1_is_vec ? type1 : type2, *v); val = vector_binop (arg1, arg2, op); } + else if (is_compound_type (type1) || is_compound_type (type2)) + val = value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL); + else + error (_("Arguments to arithmetic operation not of valid type.")); return val; } Index: valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.294 diff -u -p -r1.294 valops.c --- valops.c 21 May 2012 19:47:53 -0000 1.294 +++ valops.c 1 Jun 2012 19:00:35 -0000 @@ -2589,6 +2589,7 @@ find_overload_match (struct value **args struct value **valp, struct symbol **symp, int *staticp, const int no_adl) { + struct gdb_exception except; struct value *obj = (objp ? *objp : NULL); struct type *obj_type = obj ? value_type (obj) : NULL; /* Index of best overloaded function. */ @@ -2642,10 +2643,16 @@ find_overload_match (struct value **args } } - /* Retrieve the list of methods with the name NAME. */ - fns_ptr = value_find_oload_method_list (&temp, name, - 0, &num_fns, - &basetype, &boffset); + TRY_CATCH (except, RETURN_MASK_ERROR) + { + /* Retrieve the list of methods with the name NAME. */ + fns_ptr = value_find_oload_method_list (&temp, name, + 0, &num_fns, + &basetype, &boffset); + } + if (except.reason < 0) + fns_ptr = NULL; + /* If this is a method only search, and no methods were found the search has faild. */ if (method == METHOD && (!fns_ptr || !num_fns)) Index: testsuite/gdb.cp/operator.cc =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/operator.cc,v retrieving revision 1.2 diff -u -p -r1.2 operator.cc --- testsuite/gdb.cp/operator.cc 25 Jun 2010 18:05:30 -0000 1.2 +++ testsuite/gdb.cp/operator.cc 1 Jun 2012 19:00:36 -0000 @@ -1,7 +1,26 @@ class A { + public: + int a; + + A operator+ (const A &opr2); }; +A +A::operator+ (const A &opr2) +{ + A new_a; + new_a.a = a + opr2.a; + + return new_a; +} + +int +operator+ (const int opr1, const A &opr2) +{ + return opr1 + opr2.a; +} + int operator== (A, int) { return 11; @@ -176,6 +195,7 @@ test x; int main () { A a; + a == 1; a == 'a'; @@ -207,5 +227,9 @@ int main () L l; l == 1; - return 0; + A obj1 = { 10 }; + A obj2 = { 20 }; + int val = 1; + + return 0; /* Break here. */ } Index: testsuite/gdb.cp/operator.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/operator.exp,v retrieving revision 1.4 diff -u -p -r1.4 operator.exp --- testsuite/gdb.cp/operator.exp 4 Jan 2012 08:17:47 -0000 1.4 +++ testsuite/gdb.cp/operator.exp 1 Jun 2012 19:00:36 -0000 @@ -26,6 +26,9 @@ if ![runto_main] then { continue } +gdb_breakpoint [gdb_get_line_number "Break here."] +gdb_continue_to_breakpoint "Break here" ".*Break here.*" + # Test global operator gdb_test "p a == 1" "= 11" "global operator" gdb_test "p a == 'a'" "= 12" "global operator overload" @@ -59,3 +62,7 @@ gdb_test "p l == 1" "= 88" # Test that we don't fall into an import loop gdb_test {p x[0]} {No symbol "operator\[\]" in current context.} + +# Test + operators +gdb_test "print val + obj1" "11" "Test overloaded operator function" +gdb_test "print (obj1 + obj2).a" "30" "Test overloaded operator method" Index: testsuite/gdb.python/py-value-cc.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-value-cc.exp,v retrieving revision 1.1 diff -u -p -r1.1 py-value-cc.exp --- testsuite/gdb.python/py-value-cc.exp 22 Mar 2012 08:10:44 -0000 1.1 +++ testsuite/gdb.python/py-value-cc.exp 1 Jun 2012 19:00:37 -0000 @@ -36,6 +36,12 @@ if ![runto_main] { gdb_breakpoint [gdb_get_line_number "Break here."] gdb_continue_to_breakpoint "Break here" ".*Break here.*" +gdb_py_test_silent_cmd "python val = gdb.parse_and_eval('val')" "Create an integer value" 0 +gdb_py_test_silent_cmd "python a = gdb.parse_and_eval('a')" "Create a value for 'a'" 0 +gdb_py_test_silent_cmd "python local_a = gdb.parse_and_eval('local_a')" "Create a value for 'local_a'" 0 +gdb_py_test_silent_cmd "python new1 = val + local_a" "Excercise operator+(int, A)" 0 +gdb_py_test_silent_cmd "python new2 = a + local_a" "Excercise A::operator+(A)" 0 + gdb_test "python print str(gdb.parse_and_eval(\"a\").type)" "const A &" gdb_test "python print str(gdb.parse_and_eval(\"a\").referenced_value().type)" "const A" gdb_test "python print str(gdb.parse_and_eval(\"int_ref\").type)" "int &" @@ -46,3 +52,6 @@ gdb_test "python print str(gdb.parse_and gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().type)" "int_ptr" gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().dereference())" "10" gdb_test "python print str(gdb.parse_and_eval(\"int_ptr_ref\").referenced_value().referenced_value())" "10" + +gdb_test "python print new1" "20" "Test overloaded operator function" +gdb_test "python print new2\['a'\]" "20" "Test overlaoded operator method" Index: testsuite/gdb.python/py-value.cc =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-value.cc,v retrieving revision 1.1 diff -u -p -r1.1 py-value.cc --- testsuite/gdb.python/py-value.cc 22 Mar 2012 08:10:44 -0000 1.1 +++ testsuite/gdb.python/py-value.cc 1 Jun 2012 19:00:37 -0000 @@ -15,14 +15,35 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -class A { +class A +{ + public: + int a; + + A operator+ (const A &opr2); }; +A +A::operator+ (const A &opr2) +{ + A new_a; + new_a.a = a + opr2.a; + + return new_a; +} + +int +operator+ (const int opr1, const A &opr2) +{ + return opr1 + opr2.a; +} + typedef int *int_ptr; int func (const A &a) { + A local_a = { 10 }; int val = 10; int &int_ref = val; int_ptr ptr = &val; @@ -34,6 +55,7 @@ func (const A &a) int main () { - A obj; + A obj = { 10 }; + return func (obj); } Index: testsuite/gdb.python/py-value.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.python/py-value.exp,v retrieving revision 1.27 diff -u -p -r1.27 py-value.exp --- testsuite/gdb.python/py-value.exp 16 Jan 2012 16:21:52 -0000 1.27 +++ testsuite/gdb.python/py-value.exp 1 Jun 2012 19:00:37 -0000 @@ -109,7 +109,7 @@ proc test_value_numeric_ops {} { # Test some invalid operations. gdb_test_multiple "python print 'result = ' + str(i+'foo')" "catch error in python type conversion" { - -re "Argument to arithmetic operation not a number or boolean.*$gdb_prompt $" {pass "catch error in python type conversion"} + -re "Arguments to arithmetic operation not of valid type.*$gdb_prompt $" {pass "catch error in python type conversion"} -re "result = .*$gdb_prompt $" {fail "catch error in python type conversion"} -re "$gdb_prompt $" {fail "catch error in python type conversion"} }