ctf_die_bitsize was reading DW_AT_byte_size or DW_AT_bit_size using
AT_unsigned, which fails with an assert if the value is not constant.
This can be the case with variable length vectors such as those used
by aarch64 SVE, which CTF does not support.
Check that the size is a constant before reading with AT_unsigned in
ctf_die_bitsize, and return 0 if the entity size is variable.
This change results in such vector types being emitted in CTF as
unrepresentable types rather than causing an ICE.
Tested on x86_64-linux-gnu host for aarch64-linux-gnu and native
targets, ok for trunk?
PR debug/114016
gcc/
* dwarf2ctf.cc (is_AT_unsigned): New static helper.
(ctf_die_bitsize): Use it here before reading with AT_unsigned.
gcc/testsuite/
* gcc.dg/debug/ctf/pr114016.c: New test.
---
gcc/dwarf2ctf.cc | 17 +++++++++++++----
gcc/testsuite/gcc.dg/debug/ctf/pr114016.c | 7 +++++++
2 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/pr114016.c
diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index a561087b047..ef744e4d5ec 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -201,10 +201,19 @@ gen_ctf_unknown_type (ctf_container_ref ctfc)
return dtd;
}
+/* Return whether A can be read as AT_unsigned. */
+
+static bool
+is_AT_unsigned (dw_attr_node *a)
+{
+ return (AT_class (a) == dw_val_class_unsigned_const
+ || AT_class (a) == dw_val_class_unsigned_const_implicit);
+}
+
/* Sizes of entities can be given in bytes or bits. This function
abstracts this by returning the size in bits of the given entity.
- If no DW_AT_byte_size nor DW_AT_bit_size are defined, this function
- returns 0. */
+ If no DW_AT_byte_size nor DW_AT_bit_size are defined, or if the
+ size is variable, this function returns 0. */
static unsigned HOST_WIDE_INT
ctf_die_bitsize (dw_die_ref die)
@@ -212,9 +221,9 @@ ctf_die_bitsize (dw_die_ref die)
dw_attr_node *attr_byte_size = get_AT (die, DW_AT_byte_size);
dw_attr_node *attr_bit_size = get_AT (die, DW_AT_bit_size);
- if (attr_bit_size)
+ if (attr_bit_size && is_AT_unsigned (attr_bit_size))
return AT_unsigned (attr_bit_size);
- else if (attr_byte_size)
+ else if (attr_byte_size && is_AT_unsigned (attr_byte_size))
return (AT_unsigned (attr_byte_size) * 8);
else
return 0;
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/pr114016.c
b/gcc/testsuite/gcc.dg/debug/ctf/pr114016.c
new file mode 100644
index 00000000000..5344b293e32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/ctf/pr114016.c
@@ -0,0 +1,7 @@
+/* PR debug/114016
+ CTF generation for variable length vector using aarch64 SVE. */
+/* { dg-do compile { target aarch64-*-* } } */
+/* { dg-options "-march=armv8.2-a+sve -gctf" } */
+
+#pragma GCC aarch64 "arm_sve.h"
+svuint64x4_t *p;
--
2.51.0