Fix PR c++/23373: GDB hangs when printing a struct with a static member of itself
authorSergio Durigan Junior <sergiodj@redhat.com>
Sat, 7 Jul 2018 21:16:55 +0000 (17:16 -0400)
committerSergio Durigan Junior <sergiodj@redhat.com>
Wed, 11 Jul 2018 18:53:44 +0000 (14:53 -0400)
This patch fixes a failure that happens when a structure has a static
member whose type is the same as itself.  From the bug report:

  Example code:
  struct A
  {
      static A Empty;
      int a;
  };

  int main(void) {
      A a;
      return 0;
  }

  Output:
  (gdb) ptype/o A
  /* offset    |  size */  type = struct A {
     static struct A {
 static struct A {
     static struct A {
 static struct A {
     static struct A {
 static struct A {
     ... # infinite loop

The problem here is that GDB is not taking into account the fact that
static members inside a class/struct are not stored in the
class/struct, and therefore they should not be accounted for during
the display of the offsets/sizes.  The fix is simple: we just check if
the field we're dealing with (on
c-typeprint.c:c_type_print_base_struct_union) is static, and if it is
then we don't iterate over it.

This patch also adds a new test for this case, and doesn't introduce
any regressions.  I believe it is important enough to be included in
the 8.2 branch.

OK?

gdb/ChangeLog:
2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>

PR c++/23373
* c-typeprint.c (c_type_print_base_struct_union): Don't print
offsets/sizes for static members of a class/struct.

gdb/testsuite/ChangeLog:
2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>

PR c++/23373
* gdb.base/ptype-offsets.cc (struct static_member): New
struct.
(main) <stmember>: New variable.
* gdb.base/ptype-offsets.exp: Add test for printing a struct
with a static member in it.

gdb/ChangeLog
gdb/c-typeprint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/ptype-offsets.cc
gdb/testsuite/gdb.base/ptype-offsets.exp

index 7c74c87d8c56ffd906d292550a6f45218d81a1a9..5ac6c604f6a7605fd3b475d24dc5cd45167c4400 100644 (file)
@@ -1,3 +1,9 @@
+2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
+
+       PR c++/23373
+       * c-typeprint.c (c_type_print_base_struct_union): Don't print
+       offsets/sizes for static members of a class/struct.
+
 2018-07-11  Alan Hayward  <alan.hayward@arm.com>
 
        * target-descriptions.c (tdesc_register_bitsize): Rename.
index c167e212ded4ae12ef8110b95fc12ef98eada10c..eccb972f24576c425f9300060dd086995b678c09 100644 (file)
@@ -1168,7 +1168,7 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream,
 
          int newshow = show - 1;
 
-         if (flags->print_offsets
+         if (!is_static && flags->print_offsets
              && (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_STRUCT
                  || TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION))
            {
index d073eda401a48b452c04d7f3970142c5a336863f..f1b2a70379bb4883e1e2fe9c0c9205307b2dd522 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
+
+       PR c++/23373
+       * gdb.base/ptype-offsets.cc (struct static_member): New
+       struct.
+       (main) <stmember>: New variable.
+       * gdb.base/ptype-offsets.exp: Add test for printing a struct
+       with a static member in it.
+
 2018-07-10  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdb.base/watchpoint-reuse-slot.exp: Test with hardware
index 7b01dbc5fb46d57ff433d01f584dc5d042abf100..e1aefe5bb3f280c7f02abb0cddc03983bfcf84f8 100644 (file)
@@ -177,6 +177,13 @@ struct asd
   void *f16;
 };
 
+/* See PR c++/23373.  */
+
+struct static_member
+{
+  static static_member Empty;
+  int abc;
+};
 
 int
 main (int argc, char *argv[])
@@ -188,6 +195,7 @@ main (int argc, char *argv[])
   struct tyu e;
   struct asd f;
   uint8_t i;
+  static_member stmember;
 
   return 0;
 }
index d8718d581b1ca8643b5b21781a92f261969fac03..ca0c5de7eea433d1e7e5ef22c899b4657a8c6a28 100644 (file)
@@ -328,3 +328,14 @@ gdb_test_multiple "$test" "$test" {
        pass $test
    }
 }
+
+# Test that printing a struct with a static member of itself doesn't
+# get us into an infinite loop.
+gdb_test "ptype/o static_member" \
+    [multi_line \
+{/\* offset    |  size \*/  type = struct static_member \{} \
+{                           static static_member Empty;} \
+{\/*    0      |     4 \*/    int abc;} \
+{} \
+{                           /\* total size \(bytes\):    4 \*/} \
+{                         \}}]