diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6a0c3e4f06..c9c39199ff 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2013-02-11 Sergio Durigan Junior + + * valops.c (value_assign): Handling bitfield offset in + `lval_internalvar_component' case. + 2013-02-08 Doug Evans * common/format.c (parse_format_string): Fix whitespace. diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 7f9ab80ef1..822e031ea1 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-02-11 Sergio Durigan Junior + + * gdb.base/bitfields.c (struct internalvartest): New declaration. + * gdb.base/bitfields.exp (bitfield_internalvar): New function. + 2013-02-10 Jan Kratochvil * gdb.python/py-prompt.exp: Add to the end a kill of $testpid. diff --git a/gdb/testsuite/gdb.base/bitfields.c b/gdb/testsuite/gdb.base/bitfields.c index ed1634cf71..3a6b76fb99 100644 --- a/gdb/testsuite/gdb.base/bitfields.c +++ b/gdb/testsuite/gdb.base/bitfields.c @@ -23,6 +23,22 @@ struct fields signed char sc ; } flags; +struct internalvartest +{ + unsigned int a : 1; + struct + { + unsigned int b : 1; + struct + { + unsigned int c : 1; + signed int d : 1; + } deep; + signed int e : 1; + } inner; + signed int f : 1; +} dummy_internalvartest; + void break1 () { } diff --git a/gdb/testsuite/gdb.base/bitfields.exp b/gdb/testsuite/gdb.base/bitfields.exp index 9095736de8..82f7b1010b 100644 --- a/gdb/testsuite/gdb.base/bitfields.exp +++ b/gdb/testsuite/gdb.base/bitfields.exp @@ -245,6 +245,31 @@ proc bitfield_at_offset {} { gdb_test "print container.two.u3" ".* = 3" } +proc bitfield_internalvar {} { + global gdb_prompt + + # First, we create an internal var holding an instance of + # the struct (zeroed out). + gdb_test "set \$myvar = (struct internalvartest) \{0\}" "" \ + "set internal var" + + # Now, we set the proper bits. + gdb_test_no_output "set \$myvar.a = 0" + gdb_test_no_output "set \$myvar.inner.b = 1" + gdb_test_no_output "set \$myvar.inner.deep.c = 0" + gdb_test_no_output "set \$myvar.inner.deep.d = -1" + gdb_test_no_output "set \$myvar.inner.e = 1" + gdb_test_no_output "set \$myvar.f = 1" + + # Here comes the true testing. + gdb_test "print \$myvar.a" "\\$\[0-9\]\+ = 0" + gdb_test "print \$myvar.inner.b" "\\$\[0-9\]\+ = 1" + gdb_test "print \$myvar.inner.deep.c" "\\$\[0-9\]\+ = 0" + gdb_test "print \$myvar.inner.deep.d" "\\$\[0-9\]\+ = -1" + gdb_test "print \$myvar.inner.e" "\\$\[0-9\]\+ = -1" + gdb_test "print \$myvar.f" "\\$\[0-9\]\+ = -1" +} + gdb_start gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} @@ -256,3 +281,4 @@ bitfield_containment bitfield_unsignedness bitfield_signedness bitfield_at_offset +bitfield_internalvar diff --git a/gdb/valops.c b/gdb/valops.c index 2132f3e533..93c09d8b33 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1233,11 +1233,27 @@ value_assign (struct value *toval, struct value *fromval) VALUE_INTERNALVAR (toval)); case lval_internalvar_component: - set_internalvar_component (VALUE_INTERNALVAR (toval), - value_offset (toval), - value_bitpos (toval), - value_bitsize (toval), - fromval); + { + int offset = value_offset (toval); + + /* Are we dealing with a bitfield? + + It is important to mention that `value_parent (toval)' is + non-NULL iff `value_bitsize (toval)' is non-zero. */ + if (value_bitsize (toval)) + { + /* VALUE_INTERNALVAR below refers to the parent value, while + the offset is relative to this parent value. */ + gdb_assert (value_parent (value_parent (toval)) == NULL); + offset += value_offset (value_parent (toval)); + } + + set_internalvar_component (VALUE_INTERNALVAR (toval), + offset, + value_bitpos (toval), + value_bitsize (toval), + fromval); + } break; case lval_memory: