diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ee15e0361b..759fa2033e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2006-07-25 Daniel Jacobowitz + + * eval.c (evaluate_subexp_for_address): Don't incorrectly discard + calls to C++ operator*. + 2006-07-24 Roger Sayle Daniel Jacobowitz diff --git a/gdb/eval.c b/gdb/eval.c index 083bbc2f50..d5d8969a7b 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -2132,6 +2132,7 @@ evaluate_subexp_for_address (struct expression *exp, int *pos, enum exp_opcode op; int pc; struct symbol *var; + struct value *x; pc = (*pos); op = exp->elts[pc].opcode; @@ -2140,7 +2141,24 @@ evaluate_subexp_for_address (struct expression *exp, int *pos, { case UNOP_IND: (*pos)++; - return evaluate_subexp (NULL_TYPE, exp, pos, noside); + x = evaluate_subexp (NULL_TYPE, exp, pos, noside); + + /* We can't optimize out "&*" if there's a user-defined operator*. */ + if (unop_user_defined_p (op, x)) + { + x = value_x_unop (x, op, noside); + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + if (VALUE_LVAL (x) == lval_memory) + return value_zero (lookup_pointer_type (value_type (x)), + not_lval); + else + error (_("Attempt to take address of non-lval")); + } + return value_addr (x); + } + + return x; case UNOP_MEMVAL: (*pos) += 3; @@ -2179,16 +2197,16 @@ evaluate_subexp_for_address (struct expression *exp, int *pos, default: default_case: + x = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_AVOID_SIDE_EFFECTS) { - struct value *x = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (VALUE_LVAL (x) == lval_memory) return value_zero (lookup_pointer_type (value_type (x)), not_lval); else error (_("Attempt to take address of non-lval")); } - return value_addr (evaluate_subexp (NULL_TYPE, exp, pos, noside)); + return value_addr (x); } } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index f145210704..30189cc9ac 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-07-25 Daniel Jacobowitz + + * gdb.cp/userdef.cc, gdb.cp/userdef.exp: New tests for unary + operator*. + 2006-07-24 Daniel Jacobowitz * gdb.base/completion.exp: Update for change in "file" behavior. diff --git a/gdb/testsuite/gdb.cp/userdef.cc b/gdb/testsuite/gdb.cp/userdef.cc index 0ed81dc6af..4f2817216f 100644 --- a/gdb/testsuite/gdb.cp/userdef.cc +++ b/gdb/testsuite/gdb.cp/userdef.cc @@ -1,6 +1,6 @@ /* This test script is part of GDB, the GNU debugger. - Copyright 1999, 2002, 2003, 2004, 2005 + Copyright 1999, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify @@ -306,12 +306,31 @@ A2 A2::operator+() return A2 (); } +class Member +{ +public: + int z; +}; + +class Container +{ +public: + Member m; + + Member& operator* (); +}; + +Member& Container::operator* () +{ + return this->m; +} int main (void) { A1 one(2,3); A1 two(4,5); A1 three(0,0); + Container c; int val; marker1(); // marker1-returns-here @@ -379,6 +398,8 @@ int main (void) ++three; cout << "preinc " << three; + (*c).z = 1; + return 0; } diff --git a/gdb/testsuite/gdb.cp/userdef.exp b/gdb/testsuite/gdb.cp/userdef.exp index 834688b6b0..6a8cb046d8 100644 --- a/gdb/testsuite/gdb.cp/userdef.exp +++ b/gdb/testsuite/gdb.cp/userdef.exp @@ -1,5 +1,6 @@ # Tests of overloaded operators resolution. -# Copyright 1998, 1999, 2002, 2004, 2005 Free Software Foundation, Inc. +# Copyright 1998, 1999, 2002, 2004, 2005, 2006 +# Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -143,5 +144,11 @@ gdb_test "print two = one" "\\\$\[0-9\]* = {x = 9, y = 10}" gdb_test "break A2::'operator+'" ".*Breakpoint $decimal at.*" gdb_test "break A2::'operator +'" ".*Breakpoint $decimal at.*" +# Check that GDB handles operator* correctly. +gdb_test "print c" "\\\$\[0-9\]* = {m = {z = .*}}" +gdb_test "print *c" "\\\$\[0-9\]* = \\(Member &\\) @$hex: {z = .*}" +gdb_test "print &*c" "\\\$\[0-9\]* = \\(Member \\*\\) $hex" +gdb_test "ptype &*c" "type = struct Member {\[\r\n \]+int z;\[\r\n\]+} &\\*" + gdb_exit return 0