Lack of DW_AT_bit_stride in a DW_TAG_array_type entry causes GDB to infer
incorrect element size for vector types. The causes incorrect display of
SVE predicate variables as well as out of bounds memory access when reading
contents of SVE predicates from memory in GDB.

        PR debug/121964

gcc/
        * dwarf2out.cc
        (base_type_die): add DW_AT_bit_size attribute
        for boolean types.
        (gen_array_type_die): add DW_AT_bit_stride attribute for
        array types based on element type bit precision for integer
        and boolean element types.

gcc/testsuite/
        * g++.target/aarch64/sve/dwarf-bit-stride.C: New test.
        * gcc.target/aarch64/sve/dwarf-bit-stride.c: New test.
---

Passes regression on aarch64. OK for trunk?

base-commit: 282c1e682e0

---
 gcc/dwarf2out.cc                                  | 11 ++++++++++-
 .../g++.target/aarch64/sve/dwarf-bit-stride.C     | 15 +++++++++++++++
 .../gcc.target/aarch64/sve/dwarf-bit-stride.c     | 15 +++++++++++++++
 3 files changed, 40 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 0bd8474bc37..aaaa578ce56 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -13360,7 +13360,8 @@ base_type_die (tree type, bool reverse)
   add_AT_unsigned (base_type_result, DW_AT_byte_size,
                   int_size_in_bytes (type));
   add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);
-  if (TREE_CODE (type) == BITINT_TYPE)
+  if (TREE_CODE (type) == BITINT_TYPE
+      || TREE_CODE (type) == BOOLEAN_TYPE)
     add_AT_unsigned (base_type_result, DW_AT_bit_size, TYPE_PRECISION (type));
 
   if (need_endianity_attribute_p (reverse))
@@ -22765,6 +22766,14 @@ gen_array_type_die (tree type, dw_die_ref context_die)
   /* Add representation of the type of the elements of this array type and
      emit the corresponding DIE if we haven't done it already.  */
   element_type = TREE_TYPE (type);
+
+  /* Add bit stride information so that elements can be correctly
+     read and displayed by a debugger.  */
+  if (TREE_CODE (element_type) == BITINT_TYPE
+      || TREE_CODE (element_type) == BOOLEAN_TYPE)
+    add_AT_unsigned (array_die,
+                  DW_AT_bit_stride, TYPE_PRECISION (element_type));
+
   if (collapse_nested_arrays)
     while (TREE_CODE (element_type) == ARRAY_TYPE)
       {
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C 
b/gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C
new file mode 100644
index 00000000000..bbc967c7ffd
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dwarf-bit-stride.C
@@ -0,0 +1,15 @@
+/* { dg-do compile { target aarch64_asm_sve_ok } } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_bit_stride" 2 } }
+// { dg-final { scan-assembler-times "DW_AT_GNU_vector" 2 } }
+// { dg-final { scan-assembler-times "DW_TAG_array_type" 2 } }
+
+#include <arm_sve.h>
+
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c 
b/gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c
new file mode 100644
index 00000000000..bbc967c7ffd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/dwarf-bit-stride.c
@@ -0,0 +1,15 @@
+/* { dg-do compile { target aarch64_asm_sve_ok } } */
+// { dg-options "-g -dA" }
+// { dg-final { scan-assembler-times "DW_AT_bit_stride" 2 } }
+// { dg-final { scan-assembler-times "DW_AT_GNU_vector" 2 } }
+// { dg-final { scan-assembler-times "DW_TAG_array_type" 2 } }
+
+#include <arm_sve.h>
+
+void fun ()
+{
+  volatile svbool_t pred8 = svwhilelt_b8_u32 (0u, 1u);
+  volatile svbool_t pred16 = svwhilelt_b16_u32 (0u, 3u);
+  volatile svbool_t pred32 = svwhilelt_b32_u32 (0u, 7u);
+  volatile svbool_t pred64 = svwhilelt_b64_u32 (0u, 11u);
+}
-- 
2.47.3

Reply via email to