From b26ed50ddfdc3c3ba992ca2cfaf75b515a43b3d9 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 8 Dec 2006 12:44:11 +0000 Subject: [PATCH] 2006-12-08 Vladimir Prus * varobj.c (varobj_create): Don't call release_value. (varobj_set_value): Likewise. (install_new_value): Call coerce_ref and release_value on the value. Add asserts. --- gdb/ChangeLog | 7 +++ gdb/testsuite/ChangeLog | 10 ++++ gdb/testsuite/gdb.mi/mi-var-cp.cc | 30 ++++++++++++ gdb/testsuite/gdb.mi/mi-var-cp.exp | 73 ++++++++++++++++++++++++++++++ gdb/testsuite/lib/mi-support.exp | 38 +++++++++++++++- gdb/varobj.c | 23 +++++++--- 6 files changed, 173 insertions(+), 8 deletions(-) create mode 100644 gdb/testsuite/gdb.mi/mi-var-cp.cc create mode 100644 gdb/testsuite/gdb.mi/mi-var-cp.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index fa9f7fb6d6c..c55c669bdb4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2006-12-08 Vladimir Prus + + * varobj.c (varobj_create): Don't call release_value. + (varobj_set_value): Likewise. + (install_new_value): Call coerce_ref and release_value + on the value. Add asserts. + 2006-12-08 Nick Roberts * mi/mi-cmd-var.c (mi_cmd_var_update): Fix memory leak. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 4a84cbc55a3..d1f91e55273 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2006-12-08 Vladimir Prus + + * lib/mi-support.exp + (mi_runto): Accept "()" after function name. + (mi_create_varobj): New function. + (mi_varobj_update): New function. + (mi_Check_varobj_value): New function. + * gdb.mi/mi-var-cp.exp: New file. + * gdb.mi/mi-var-cp.cc: New file. + 2006-12-01 Daniel Jacobowitz * gdb.base/solib-weak.c, gdb.base/solib-weak.exp, gdb.base/weaklib1.c, diff --git a/gdb/testsuite/gdb.mi/mi-var-cp.cc b/gdb/testsuite/gdb.mi/mi-var-cp.cc new file mode 100644 index 00000000000..23390f90389 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-cp.cc @@ -0,0 +1,30 @@ +/* Copyright 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +void reference_update_tests () +{ + int x = 167; + int& rx = x; + x = 567; + x = 567; +} + +int main () +{ + reference_update_tests (); + return 0; +} diff --git a/gdb/testsuite/gdb.mi/mi-var-cp.exp b/gdb/testsuite/gdb.mi/mi-var-cp.exp new file mode 100644 index 00000000000..ea9d3de8bc9 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi-var-cp.exp @@ -0,0 +1,73 @@ +# Copyright 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 +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if { [skip_cplus_tests] } { continue } + +load_lib mi-support.exp +set MIFLAGS "-i=mi" + +gdb_exit +if [mi_gdb_start] { + continue +} + +set testfile mi-var-cp +set srcfile "$testfile.cc" +set binfile $objdir/$subdir/$testfile + +if [get_compiler_info ${binfile} "c++"] { + return -1; +} + +if {[gdb_compile $srcdir/$subdir/$srcfile $binfile executable {debug c++}] != ""} { + untested $testfile.exp + return -1 +} + +mi_gdb_load ${binfile} + +# Test that children of classes are properly reported + +# Run to main +mi_runto reference_update_tests + +mi_create_varobj "RX" "rx" "create varobj for rx" + +set x_assignment [gdb_get_line_number "x = 567;"] +mi_next_to "reference_update_tests" {} ".*${srcfile}" [expr $x_assignment-1] \ + "step to x assignment" +mi_next_to "reference_update_tests" {} ".*${srcfile}" [expr $x_assignment] \ + "step to x assignment" + +mi_varobj_update RX {RX} "update RX (1)" + +mi_check_varobj_value RX 167 "check RX: expect 167" + +# Execute the first 'x = 567' line. +mi_next_to "reference_update_tests" {} ".*${srcfile}" [expr $x_assignment+1] \ + "step to x assignment" + +mi_varobj_update RX {RX} "update RX (2)" +mi_check_varobj_value RX 567 "check RX: expect 567" + +# Execute the second 'x = 567' line. +mi_next_to "reference_update_tests" {} ".*${srcfile}" [expr $x_assignment+2] \ + "step to x assignment" + +mi_varobj_update RX {} "update RX (3)" + +mi_gdb_exit +return 0 diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index 5d5af947152..af3feefa741 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -869,7 +869,7 @@ proc mi_runto {func} { set test "mi runto $func" mi_gdb_test "200-break-insert $func" \ - "200\\^done,bkpt=\{number=\"\[0-9\]+\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"$func\",file=\".*\",line=\"\[0-9\]*\",times=\"0\"\}" \ + "200\\^done,bkpt=\{number=\"\[0-9\]+\",type=\"breakpoint\",disp=\"keep\",enabled=\"y\",addr=\"$hex\",func=\"$func\(\\\(.*\\\)\)?\",file=\".*\",line=\"\[0-9\]*\",times=\"0\"\}" \ "breakpoint at $func" if {![regexp {number="[0-9]+"} $expect_out(buffer) str] @@ -998,3 +998,39 @@ proc mi0_continue_to { bkptno func args file line test } { mi0_execute_to "exec-continue" "breakpoint-hit\",bkptno=\"$bkptno" \ "$func" "$args" "$file" "$line" "" "$test" } + +# Creates varobj named NAME for EXPRESSION. +# Name cannot be "-". +proc mi_create_varobj { name expression testname } { + mi_gdb_test "-var-create $name * $expression" \ + "\\^done,name=\"$name\",numchild=\"\[0-9\]+\",type=.*" \ + $testname +} + +# Updates varobj named NAME and checks that all varobjs in EXPECTED +# are reported as updated, and no other varobj is updated. +# Assumes that no varobj is out of scope and that no varobj changes +# types. +proc mi_varobj_update { name expected testname } { + set er "\\^done,changelist=\\\[" + set first 1 + foreach item $expected { + set v "{name=\"$item\",in_scope=\"true\",type_changed=\"false\"}" + if {$first} { + set er "$er$v" + } else { + set er "$er,$v" + } + } + set er "$er\\\]" + + verbose -log "Expecting: $er" 2 + mi_gdb_test "-var-update $name" $er $testname +} + +proc mi_check_varobj_value { name value testname } { + + mi_gdb_test "-var-evaluate-expression $name" \ + "\\^done,value=\"$value\"" \ + $testname +} diff --git a/gdb/varobj.c b/gdb/varobj.c index a06aab8f296..ae247c5c98f 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -512,10 +512,7 @@ varobj_create (char *objname, right type. */ value = evaluate_type (var->root->exp); - release_value (value); - var->type = value_type (value); - install_new_value (var, value, 1 /* Initial assignment */); /* Set language info */ @@ -847,9 +844,7 @@ varobj_set_value (struct varobj *var, char *expression) with catch the exception. */ if (!gdb_value_assign (var->value, value, &val)) return 0; - - release_value (val); - + /* If the value has changed, record it, so that next -var-update can report this change. If a variable had a value of '1', we've set it to '333' and then set again to '1', when -var-update will report this @@ -901,7 +896,10 @@ varobj_list (struct varobj ***varlist) and return 0. Otherwise, assign the value and if type_changeable returns non-zero, find if the new value is different from the current value. - Return 1 if so, and 0 if the values are equal. */ + Return 1 if so, and 0 if the values are equal. + + The VALUE parameter should not be released -- the function will + take care of releasing it when needed. */ static int install_new_value (struct varobj *var, struct value *value, int initial) { @@ -917,6 +915,15 @@ install_new_value (struct varobj *var, struct value *value, int initial) changeable = type_changeable (var); need_to_fetch = changeable; + /* We are not interested in the address of references, and given + that in C++ a reference is not rebindable, it cannot + meaningfully change. So, get hold of the real value. */ + if (value) + { + value = coerce_ref (value); + release_value (value); + } + if (var->type && TYPE_CODE (var->type) == TYPE_CODE_UNION) /* For unions, we need to fetch the value implicitly because of implementation of union member fetch. When gdb @@ -985,6 +992,8 @@ install_new_value (struct varobj *var, struct value *value, int initial) value_free (var->value); var->value = value; var->updated = 0; + + gdb_assert (!var->value || value_type (var->value)); return changed; } -- 2.30.2