[v3,amd64] Fix AMD64 return value ABI in expression evaluation
Commit Message
>>> This ABI mismatch resulted in issues when calling a function that returns
>>> a class of size <16 bytes which has a base class, including issues such
>>> as the "this" pointer being incorrect (as it was passed as the second
>>> argument rather than the first).
Tom> I'm still looking into the problem, but this regressed an internal test
Tom> case here at AdaCore. In particular, this patch doesn't seem to treat
Tom> bitfields the same way that gcc does.
The appended fixes the test case that's included, but I'm not really
sure it's correct, since I am not sure that the test for
"bit-field-ness" is correct here.
Let me know what you think.
Tom
commit 93fb3e610bcd0ff5763334588bd84e41a4f73ef9
Author: Tom Tromey <tromey@adacore.com>
Date: Tue Apr 16 11:11:10 2019 -0600
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-16 Tom Tromey <tromey@adacore.com>
* amd64-tdep.c (amd64_has_unaligned_fields): Ignore bitfields.
gdb/testsuite/ChangeLog
2019-04-16 Tom Tromey <tromey@adacore.com>
* gdb.arch/amd64-eval.exp: Test bitfield return.
* gdb.arch/amd64-eval.cc (struct Bitfields): New.
(class Foo) <return_bitfields>: New method.
(main): Call it.
Comments
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:
Tom> The appended fixes the test case that's included, but I'm not really
Tom> sure it's correct, since I am not sure that the test for
Tom> "bit-field-ness" is correct here.
Tom> Let me know what you think.
I'm checking this in now.
It seems to me that since this fixes the regression and also does not
regress the other new tests that it must be at least an improvement.
Tom
@@ -1,3 +1,7 @@
+2019-04-16 Tom Tromey <tromey@adacore.com>
+
+ * amd64-tdep.c (amd64_has_unaligned_fields): Ignore bitfields.
+
2019-04-15 Leszek Swirski <leszeks@google.com>
* amd64-tdep.c (amd64_classify_aggregate): Use cp_pass_by_reference
@@ -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;
}
}
@@ -1,3 +1,10 @@
+2019-04-16 Tom Tromey <tromey@adacore.com>
+
+ * gdb.arch/amd64-eval.exp: Test bitfield return.
+ * gdb.arch/amd64-eval.cc (struct Bitfields): New.
+ (class Foo) <return_bitfields>: New method.
+ (main): Call it.
+
2019-04-15 Leszek Swirski <leszeks@google.com>
* gdb.arch/amd64-eval.cc: New file.
@@ -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
}
@@ -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)" \
" = {<UnalignedFields> = {x = 23, y = 4.5}, x2 = 67}"
+gdb_test "call foo.return_bitfields(23, 74)" \
+ " = {fld = 23, fld2 = 74}"