From a59240a41ac34d91e4ef5dd8b484763639388364 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 16 Apr 2019 11:11:10 -0600 Subject: [PATCH] Fix passing of struct with bitfields on x86-64 Commit 4aa866af ("Fix AMD64 return value ABI in expression evaluation") introduced a regression when calling a function with a structure that contains bitfields. Because the caller of amd64_has_unaligned_fields handles bitfields already, it seemed to me that the simplest fix was to ignore bitfields here. gdb/ChangeLog 2019-04-24 Tom Tromey * amd64-tdep.c (amd64_has_unaligned_fields): Ignore bitfields. gdb/testsuite/ChangeLog 2019-04-24 Tom Tromey * gdb.arch/amd64-eval.exp: Test bitfield return. * gdb.arch/amd64-eval.cc (struct Bitfields): New. (class Foo) : New method. (main): Call it. --- gdb/ChangeLog | 4 ++++ gdb/amd64-tdep.c | 10 ++++++---- gdb/testsuite/ChangeLog | 7 +++++++ gdb/testsuite/gdb.arch/amd64-eval.cc | 18 ++++++++++++++++++ gdb/testsuite/gdb.arch/amd64-eval.exp | 2 ++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5c40683d3f6..490c1817626 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2019-04-24 Tom Tromey + + * amd64-tdep.c (amd64_has_unaligned_fields): Ignore bitfields. + 2019-04-23 Andrew Burgess * s12z-tdep.c (s12z_unwind_pc): Delete. diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index d4c96de5716..31791f9a9f1 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -555,11 +555,13 @@ amd64_has_unaligned_fields (struct type *type) int bitpos = TYPE_FIELD_BITPOS (type, i); int align = type_align(subtype); - /* Ignore static fields, or empty fields, for example nested - empty structures. */ + /* Ignore static fields, empty fields (for example nested + empty structures), and bitfields (these are handled by + the caller). */ if (field_is_static (&TYPE_FIELD (type, i)) || (TYPE_FIELD_BITSIZE (type, i) == 0 - && TYPE_LENGTH (subtype) == 0)) + && TYPE_LENGTH (subtype) == 0) + || TYPE_FIELD_PACKED (type, i)) continue; if (bitpos % 8 != 0) @@ -569,7 +571,7 @@ amd64_has_unaligned_fields (struct type *type) if (bytepos % align != 0) return true; - if (amd64_has_unaligned_fields(subtype)) + if (amd64_has_unaligned_fields (subtype)) return true; } } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 04fecfa10a0..23ff7bc433d 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-04-24 Tom Tromey + + * gdb.arch/amd64-eval.exp: Test bitfield return. + * gdb.arch/amd64-eval.cc (struct Bitfields): New. + (class Foo) : New method. + (main): Call it. + 2019-04-23 Andrew Burgess * gdb.cp/many-args.cc: New file. diff --git a/gdb/testsuite/gdb.arch/amd64-eval.cc b/gdb/testsuite/gdb.arch/amd64-eval.cc index a986a49db34..907233ff04a 100644 --- a/gdb/testsuite/gdb.arch/amd64-eval.cc +++ b/gdb/testsuite/gdb.arch/amd64-eval.cc @@ -63,6 +63,16 @@ struct UnalignedFieldsInBase : public UnalignedFields int32_t x2; }; +struct Bitfields +{ + Bitfields(unsigned int x, unsigned int y) + : fld(x), fld2(y) + {} + + unsigned fld : 7; + unsigned fld2 : 7; +}; + class Foo { public: @@ -101,6 +111,13 @@ public: return UnalignedFieldsInBase (x, y, x2); } + Bitfields + return_bitfields (unsigned int x, unsigned int y) + { + assert (this->tag == EXPECTED_TAG); + return Bitfields(x, y); + } + private: /* Use a tag to detect if the "this" value is correct. */ static const int EXPECTED_TAG = 0xF00F00F0; @@ -116,5 +133,6 @@ main (int argc, char *argv[]) foo.return_non_trivial_destructor(3); foo.return_unaligned(4, 5); foo.return_unaligned_in_base(6, 7, 8); + foo.return_bitfields(23, 74); return 0; // break-here } diff --git a/gdb/testsuite/gdb.arch/amd64-eval.exp b/gdb/testsuite/gdb.arch/amd64-eval.exp index c33777d2b41..beef46ad133 100644 --- a/gdb/testsuite/gdb.arch/amd64-eval.exp +++ b/gdb/testsuite/gdb.arch/amd64-eval.exp @@ -41,3 +41,5 @@ gdb_test "call foo.return_unaligned(78, 9.25)" \ " = {x = 78, y = 9.25}" gdb_test "call foo.return_unaligned_in_base(23, 4.5, 67)" \ " = { = {x = 23, y = 4.5}, x2 = 67}" +gdb_test "call foo.return_bitfields(23, 74)" \ + " = {fld = 23, fld2 = 74}" -- 2.30.2