summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2019-01-24 08:17:39 +0000
committerAlan Hayward <alan.hayward@arm.com>2019-01-24 08:26:07 +0000
commit353229bf405113e6ba2fe21f2a691bc63aa94bd8 (patch)
tree7a8e1d2774cf12dd5d77d390ebce0a3900fb2570
parent388a192d73df7439bf375d8b8042bb53a6be9c60 (diff)
downloadbinutils-gdb-353229bf405113e6ba2fe21f2a691bc63aa94bd8.tar.gz
AArch64 AAPCS: Ignore static members
Static members in C++ structs are global data and therefore not part of the list of struct members considered for passing in registers. Note the corresponding code in GCC (from which the GDB AAPCS code is based) does not have any static member checks due to the static members not being part of the struct type at that point. Extend gdb.base/infcall-nested-structs.exp to test structs with static members when compiled for C++. XFAIL more cases for x86_64 (see gdb/24104). For completeness, ensure some test cases have both empty structures and static members. Also fixes gdb.dwarf2/dw2-cp-infcall-ref-static.exp. gdb/ChangeLog: * aarch64-tdep.c (aapcs_is_vfp_call_or_return_candidate_1): Check for static members. (pass_in_v_vfp_candidate): Likewise. gdb/testsuite/ChangeLog: * gdb.base/infcall-nested-structs.c (struct struct_static_02_01): New structure. (struct struct_static_02_02): Likewise. (struct struct_static_02_03): Likewise. (struct struct_static_02_04): Likewise. (struct struct_static_04_01): Likewise. (struct struct_static_04_02): Likewise. (struct struct_static_04_03): Likewise. (struct struct_static_04_04): Likewise. (struct struct_static_06_01): Likewise. (struct struct_static_06_02): Likewise. (struct struct_static_06_03): Likewise. (struct struct_static_06_04): Likewise. (cmp_struct_static_02_01): Likewise. (cmp_struct_static_02_02): Likewise. (cmp_struct_static_02_03): Likewise. (cmp_struct_static_02_04): Likewise. (cmp_struct_static_04_01): Likewise. (cmp_struct_static_04_02): Likewise. (cmp_struct_static_04_03): Likewise. (cmp_struct_static_04_04): Likewise. (cmp_struct_static_06_01): Likewise. (cmp_struct_static_06_02): Likewise. (cmp_struct_static_06_03): Likewise. (cmp_struct_static_06_04): Likewise. (call_all): Test new structs. * gdb.base/infcall-nested-structs.exp: Likewise.
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/aarch64-tdep.c8
-rw-r--r--gdb/testsuite/ChangeLog30
-rw-r--r--gdb/testsuite/gdb.base/infcall-nested-structs.c173
-rw-r--r--gdb/testsuite/gdb.base/infcall-nested-structs.exp24
5 files changed, 235 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e01f5eecb4c..453677e5999 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2019-01-24 Alan Hayward <alan.hayward@arm.com>
+
+ * aarch64-tdep.c (aapcs_is_vfp_call_or_return_candidate_1): Check
+ for static members.
+ (pass_in_v_vfp_candidate): Likewise.
+
2019-01-23 Tom Tromey <tom@tromey.com>
Pedro Alves <palves@redhat.com>
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 7c5d74858d1..fb79b570b2b 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1224,6 +1224,10 @@ aapcs_is_vfp_call_or_return_candidate_1 (struct type *type,
for (int i = 0; i < TYPE_NFIELDS (type); i++)
{
+ /* Ignore any static fields. */
+ if (field_is_static (&TYPE_FIELD (type, i)))
+ continue;
+
struct type *member = check_typedef (TYPE_FIELD_TYPE (type, i));
int sub_count = aapcs_is_vfp_call_or_return_candidate_1
@@ -1502,6 +1506,10 @@ pass_in_v_vfp_candidate (struct gdbarch *gdbarch, struct regcache *regcache,
case TYPE_CODE_UNION:
for (int i = 0; i < TYPE_NFIELDS (arg_type); i++)
{
+ /* Don't include static fields. */
+ if (field_is_static (&TYPE_FIELD (arg_type, i)))
+ continue;
+
struct value *field = value_primitive_field (arg, 0, i, arg_type);
struct type *field_type = check_typedef (value_type (field));
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 7d8c7908fe5..a4ab85ff844 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,33 @@
+2019-01-24 Alan Hayward <alan.hayward@arm.com>
+
+ * gdb.base/infcall-nested-structs.c (struct struct_static_02_01):
+ New structure.
+ (struct struct_static_02_02): Likewise.
+ (struct struct_static_02_03): Likewise.
+ (struct struct_static_02_04): Likewise.
+ (struct struct_static_04_01): Likewise.
+ (struct struct_static_04_02): Likewise.
+ (struct struct_static_04_03): Likewise.
+ (struct struct_static_04_04): Likewise.
+ (struct struct_static_06_01): Likewise.
+ (struct struct_static_06_02): Likewise.
+ (struct struct_static_06_03): Likewise.
+ (struct struct_static_06_04): Likewise.
+ (cmp_struct_static_02_01): Likewise.
+ (cmp_struct_static_02_02): Likewise.
+ (cmp_struct_static_02_03): Likewise.
+ (cmp_struct_static_02_04): Likewise.
+ (cmp_struct_static_04_01): Likewise.
+ (cmp_struct_static_04_02): Likewise.
+ (cmp_struct_static_04_03): Likewise.
+ (cmp_struct_static_04_04): Likewise.
+ (cmp_struct_static_06_01): Likewise.
+ (cmp_struct_static_06_02): Likewise.
+ (cmp_struct_static_06_03): Likewise.
+ (cmp_struct_static_06_04): Likewise.
+ (call_all): Test new structs.
+ * gdb.base/infcall-nested-structs.exp: Likewise.
+
2019-01-21 Alan Hayward <alan.hayward@arm.com>
* gdb.base/infcall-nested-structs.exp: Test C++ in addition to C.
diff --git a/gdb/testsuite/gdb.base/infcall-nested-structs.c b/gdb/testsuite/gdb.base/infcall-nested-structs.c
index 5c25956c50a..b6f793e7a33 100644
--- a/gdb/testsuite/gdb.base/infcall-nested-structs.c
+++ b/gdb/testsuite/gdb.base/infcall-nested-structs.c
@@ -21,6 +21,11 @@
scalar fields, the fields can be inside nested structures, and there can
be empty structures around too.
+ When compiled for C++ this file also tests structures containing static
+ members (which live in global memory). In addition, empty structures in C++
+ have a size of 1 (compared to 0 in GNU C), which can effect structure
+ padding.
+
This test is specifically written for RiscV and Aarch64, which both have
special ABI rules for structures like these, however, there should be no harm
in running these tests on other targets, though in many cases the
@@ -97,6 +102,32 @@ struct struct_05_02 { tA a; struct { struct { ES(es1); } s1; } s2; tB b; struct
struct struct_05_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct { struct { tA a; } s3; } s4; struct { struct { tB b; } s5; } s6; struct { struct { tA c; } s7; } s8; struct { struct { tB d; } s9; } s10; struct { struct { tA e; } s11; } s12;};
struct struct_05_04 { ES(es1); ES(es2); tA a; ES(es3); tB b; ES(es4); tA c; ES(es5); tB d; ES(es6); tA e; };
+/* Only C++ allows structures to have static members. */
+#ifdef __cplusplus
+
+/* Structures with two fields nested to various depths, one of which is static.
+ Some include empty structures. */
+struct struct_static_02_01 { struct sa { struct sb { tA a; static tB b; } s1; } s2; };
+struct struct_static_02_02 { static tA a; struct { struct { ES(es1); } s1; } s2; tB b; };
+struct struct_static_02_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct { struct { tA a; } s3; } s4; struct sa { struct sb { static tB b; } s5; } s6;};
+struct struct_static_02_04 { static tA a; tB b; };
+
+/* Structures with four fields nested to various depths, some of which are
+ static. Some include empty structures. */
+struct struct_static_04_01 { struct sa { struct sb { static tA a; tB b; tA c; tB d; } s1; } s2; };
+struct struct_static_04_02 { tA a; struct { struct { ES(es1); } s1; } s2; tB b; struct { struct { ES(es1); } s2; } s3; static tA c; struct { struct { ES(es2); } s4; } s5; static tB d;};
+struct struct_static_04_03 { struct sa { struct sb { static tA a; } s3; } s4; struct sc { struct sd { static tB b; } s5; } s6; struct se { struct sf { static tA c; } s7; } s8; struct sg { struct sh { static tB d; } s9; } s10;};
+struct struct_static_04_04 { ES(es1); ES(es2); tA a; ES(es3); tB b; ES(es4); tA c; ES(es5); static tB d; };
+
+/* Structures with six fields nested to various depths, some of which are
+ static. Some include empty structures. */
+struct struct_static_06_01 { struct sa { struct sb { tA a; static tB b; tA c; tB d; tA e; } s1; } s2; tB f; };
+struct struct_static_06_02 { tA a; static tB b; static tA c; tB d; tB e; tA f;};
+struct struct_static_06_03 { struct { struct { ES(es1); } s1; } s2; ES(es1); struct sa { struct sb { static tA a; } s3; } s4; struct sc { struct sd { tB b; } s5; } s6; struct se { struct sf { static tA c; } s7; } s8; struct sg { struct sh { static tB d; } s9; } s10; struct { struct { tA e; tB f; } s11; } s12;};
+struct struct_static_06_04 { ES(es1); ES(es2); static tA a; ES(es3); static tB b; ES(es4); static tA c; ES(es5); static tB d; ES(es6); static tA e; ES(es7); tB f; };
+
+#endif
+
int cmp_struct_01_01 (struct struct_01_01 a, struct struct_01_01 b)
{ return a.s2.s1.a == b.s2.s1.a; }
@@ -151,6 +182,78 @@ int cmp_struct_05_03 (struct struct_05_03 a, struct struct_05_03 b)
int cmp_struct_05_04 (struct struct_05_04 a, struct struct_05_04 b)
{ return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e; }
+#ifdef __cplusplus
+
+int
+cmp_struct_static_02_01 (struct struct_static_02_01 a,
+ struct struct_static_02_01 b)
+{ return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == a.s2.s1.b; }
+
+int
+cmp_struct_static_02_02 (struct struct_static_02_02 a,
+ struct struct_static_02_02 b)
+{ return a.a == b.a && a.b == b.b; }
+
+int
+cmp_struct_static_02_03 (struct struct_static_02_03 a,
+ struct struct_static_02_03 b)
+{ return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b; }
+
+int
+cmp_struct_static_02_04 (struct struct_static_02_04 a,
+ struct struct_static_02_04 b)
+{ return a.a == b.a && a.b == b.b; }
+
+int
+cmp_struct_static_04_01 (struct struct_static_04_01 a,
+ struct struct_static_04_01 b)
+{ return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == a.s2.s1.b
+ && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == a.s2.s1.d; }
+
+int
+cmp_struct_static_04_02 (struct struct_static_04_02 a,
+ struct struct_static_04_02 b)
+{ return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d; }
+
+int
+cmp_struct_static_04_03 (struct struct_static_04_03 a,
+ struct struct_static_04_03 b)
+{ return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b
+ && a.s8.s7.c == b.s8.s7.c && a.s10.s9.d == b.s10.s9.d; }
+
+int
+cmp_struct_static_04_04 (struct struct_static_04_04 a,
+ struct struct_static_04_04 b)
+{ return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d; }
+
+int
+cmp_struct_static_06_01 (struct struct_static_06_01 a,
+ struct struct_static_06_01 b)
+{ return a.s2.s1.a == b.s2.s1.a && a.s2.s1.b == a.s2.s1.b
+ && a.s2.s1.c == b.s2.s1.c && a.s2.s1.d == a.s2.s1.d
+ && a.s2.s1.e == b.s2.s1.e && a.f == b.f; }
+
+int
+cmp_struct_static_06_02 (struct struct_static_06_02 a,
+ struct struct_static_06_02 b)
+{ return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e
+ && a.f == b.f; }
+
+int
+cmp_struct_static_06_03 (struct struct_static_06_03 a,
+ struct struct_static_06_03 b)
+{ return a.s4.s3.a == b.s4.s3.a && a.s6.s5.b == b.s6.s5.b
+ && a.s8.s7.c == b.s8.s7.c && a.s10.s9.d == b.s10.s9.d
+ && a.s12.s11.e == b.s12.s11.e && a.s12.s11.f == b.s12.s11.f; }
+
+int
+cmp_struct_static_06_04 (struct struct_static_06_04 a,
+ struct struct_static_06_04 b)
+{ return a.a == b.a && a.b == b.b && a.c == b.c && a.d == b.d && a.e == b.e
+ && a.f == b.f; }
+
+#endif
+
REF_VAL(struct_01_01) = { {}, { { 'a' } } };
REF_VAL(struct_01_02) = { 'a', { { {} } } };
REF_VAL(struct_01_03) = { { { {} } }, {}, { { 'a' } } };
@@ -171,6 +274,48 @@ REF_VAL(struct_05_02) = { 'a', { { {} } }, 'b', { { {} } }, 'c', { { {} } }, 'd'
REF_VAL(struct_05_03) = { { { {} } }, {}, { { 'a' } }, { { 'b' } }, { { 'c' } }, { { 'd' } }, { { 'e' } } };
REF_VAL(struct_05_04) = { {}, {}, 'a', {}, 'b', {}, 'c', {}, 'd', {}, 'e' };
+#ifdef __cplusplus
+
+/* Initialise static members. */
+tB struct_static_02_01::sa::sb::b = '1';
+tA struct_static_02_02::a = '2';
+tB struct_static_02_03::sa::sb::b = '3';
+tA struct_static_02_04::a = '4';
+tA struct_static_04_01::sa::sb::a = '5';
+tA struct_static_04_02::c = '6';
+tB struct_static_04_02::d = '7';
+tA struct_static_04_03::sa::sb::a = '8';
+tB struct_static_04_03::sc::sd::b = '9';
+tA struct_static_04_03::se::sf::c = '0';
+tB struct_static_04_03::sg::sh::d = 'A';
+tB struct_static_04_04::d = 'B';
+tB struct_static_06_01::sa::sb::b = 'C';
+tB struct_static_06_02::b = 'D';
+tA struct_static_06_02::c = 'E';
+tA struct_static_06_03::sa::sb::a = 'F';
+tA struct_static_06_03::se::sf::c = 'G';
+tB struct_static_06_03::sg::sh::d = 'H';
+tA struct_static_06_04::a = 'I';
+tB struct_static_06_04::b = 'J';
+tA struct_static_06_04::c = 'K';
+tB struct_static_06_04::d = 'L';
+tA struct_static_06_04::e = 'M';
+
+REF_VAL(struct_static_02_01) = { { { 'a' } } };
+REF_VAL(struct_static_02_02) = { { { {} } }, 'b' };
+REF_VAL(struct_static_02_03) = { { { {} } }, {}, { { 'a' } }, { { } } };
+REF_VAL(struct_static_02_04) = { 'b' };
+REF_VAL(struct_static_04_01) = { { { 'b', 'c', 'd' } } };
+REF_VAL(struct_static_04_02) = { 'a', { { {} } }, 'b', { { {} } }, { { {} } } };
+REF_VAL(struct_static_04_03) = {};
+REF_VAL(struct_static_04_04) = { {}, {}, 'a', {}, 'b', {}, 'c', {} };
+REF_VAL(struct_static_06_01) = { { { 'a', 'c', 'd', 'e' } }, 'f' };
+REF_VAL(struct_static_06_02) = { 'a', 'd', 'e', 'f' };
+REF_VAL(struct_static_06_03) = { { { {} } }, {}, {}, { { 'b' } }, {}, /*{ { 'e', 'f' } }*/ };
+REF_VAL(struct_static_06_04) = { {}, {}, {}, {}, {}, {}, {}, 'f' };
+
+#endif
+
/* Create all of the functions GDB will call to check functionality. */
MAKE_CHECK_FUNCS(struct_01_01)
MAKE_CHECK_FUNCS(struct_01_02)
@@ -188,6 +333,20 @@ MAKE_CHECK_FUNCS(struct_05_01)
MAKE_CHECK_FUNCS(struct_05_02)
MAKE_CHECK_FUNCS(struct_05_03)
MAKE_CHECK_FUNCS(struct_05_04)
+#ifdef __cplusplus
+MAKE_CHECK_FUNCS(struct_static_02_01)
+MAKE_CHECK_FUNCS(struct_static_02_02)
+MAKE_CHECK_FUNCS(struct_static_02_03)
+MAKE_CHECK_FUNCS(struct_static_02_04)
+MAKE_CHECK_FUNCS(struct_static_04_01)
+MAKE_CHECK_FUNCS(struct_static_04_02)
+MAKE_CHECK_FUNCS(struct_static_04_03)
+MAKE_CHECK_FUNCS(struct_static_04_04)
+MAKE_CHECK_FUNCS(struct_static_06_01)
+MAKE_CHECK_FUNCS(struct_static_06_02)
+MAKE_CHECK_FUNCS(struct_static_06_03)
+MAKE_CHECK_FUNCS(struct_static_06_04)
+#endif
#define CALL_LINE(NAME) val += check_arg_ ## NAME (rtn_str_ ## NAME ())
@@ -212,6 +371,20 @@ call_all ()
CALL_LINE(struct_05_02);
CALL_LINE(struct_05_03);
CALL_LINE(struct_05_04);
+#ifdef __cplusplus
+ CALL_LINE(struct_static_02_01);
+ CALL_LINE(struct_static_02_02);
+ CALL_LINE(struct_static_02_03);
+ CALL_LINE(struct_static_02_04);
+ CALL_LINE(struct_static_04_01);
+ CALL_LINE(struct_static_04_02);
+ CALL_LINE(struct_static_04_03);
+ CALL_LINE(struct_static_04_04);
+ CALL_LINE(struct_static_06_01);
+ CALL_LINE(struct_static_06_02);
+ CALL_LINE(struct_static_06_03);
+ CALL_LINE(struct_static_06_04);
+#endif
return (val != 4);
}
diff --git a/gdb/testsuite/gdb.base/infcall-nested-structs.exp b/gdb/testsuite/gdb.base/infcall-nested-structs.exp
index d7d1e3e00d8..f5fbf44ed16 100644
--- a/gdb/testsuite/gdb.base/infcall-nested-structs.exp
+++ b/gdb/testsuite/gdb.base/infcall-nested-structs.exp
@@ -122,13 +122,25 @@ proc run_tests { lang types } {
foreach {name} {struct_01_01 struct_01_02 struct_01_03 struct_01_04
struct_02_01 struct_02_02 struct_02_03 struct_02_04
struct_04_01 struct_04_02 struct_04_03 struct_04_04
- struct_05_01 struct_05_02 struct_05_03 struct_05_04} {
+ struct_05_01 struct_05_02 struct_05_03 struct_05_04
+ struct_static_02_01 struct_static_02_02 struct_static_02_03 struct_static_02_04
+ struct_static_04_01 struct_static_04_02 struct_static_04_03 struct_static_04_04
+ struct_static_06_01 struct_static_06_02 struct_static_06_03 struct_static_06_04} {
+
+ # Only run static member tests on C++
+ if { $lang == "c" && [regexp "static" $name match] } {
+ continue
+ }
- if { ( $lang == "c++"
- && ( ( [regexp "struct_01_0(1|2|3)" $name match] && [regexp "^types-(td($|-)|tl(|l)(|-tf|-td|-tld)$)" $types match] )
- || ( $name == "struct_01_02" && $types == "types-tfc" )
- || ( $name == "struct_01_04" && [regexp "^types-(tf($|-)|ti(|-tf|-td|-tld)$)" $types match] )
- || ( $name == "struct_02_01" && [regexp "^types-tf-t(c|s|i)" $types match] ) ) ) } {
+ if { $lang == "c++"
+ && ( ( [regexp "struct_01_0(1|2|3)" $name match] && [regexp "^types-(td($|-)|tl(|l)(|-tf|-td|-tld)$)" $types match] )
+ || ( $name == "struct_01_02" && $types == "types-tfc" )
+ || ( $name == "struct_01_04" && [regexp "^types-(tf($|-)|ti(|-tf|-td|-tld)$)" $types match] )
+ || ( $name == "struct_02_01" && [regexp "^types-tf-t(c|s|i)" $types match] )
+ || ( $name == "struct_static_02_02" && [regexp "^types-(t(f|d|ld)-t(d|l|ll)$|t(d|l|ll)$|t(c|s|i|l|ll)-td)" $types match] )
+ || ( $name == "struct_static_02_03" && [regexp "^types-(ti-t(f|l|d|)|tf(-|$)|ti$)" $types match] )
+ || ( $name == "struct_static_04_02" && [regexp "^types-(t(c|s)-tf|tf-ts)" $types match] )
+ || ( $name == "struct_static_06_04" && ![regexp "^types-(t(c|dc|ldc|ld)$|t.-tld|tl(l|d)-tld|t(f|d|ld)-tc)" $types match] ) ) } {
setup_xfail gdb/24104 "x86_64-*-linux*"
}
gdb_test "p/d check_arg_${name} (ref_val_${name})" "= 1"