summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-03-01 14:57:15 +0100
committerJakub Jelinek <jakub@redhat.com>2024-03-01 14:57:15 +0100
commit5b1fb8f8b4fe60745dece9b2f83c155c772ca66d (patch)
tree27daaa7b7bc10991110954c0578de6591e64be1d
parent270d0f69cffbfa81f61c5a6b7f7de2c5919703c7 (diff)
dwarf2out: Don't move variable sized aggregates to comdat [PR114015]
The following testcase ICEs, because we decide to move that struct { char a[n]; } DW_TAG_structure_type into .debug_types section / DW_UT_type DWARF5 unit, but refer from there to a DW_TAG_variable (created artificially for the array bounds). Even with non-bitint, I think it is just wrong to use .debug_types section / DW_UT_type for something that uses DW_OP_fbreg and similar in it, things clearly dependent on a particular function. In most cases, is_nested_in_subprogram (die) check results in such aggregates not being moved, but in the function parameter type case that is not the case. The following patch fixes it by returning false from should_move_die_to_comdat for non-constant sized aggregate types, i.e. when either we gave up on adding DW_AT_byte_size for it because it wasn't expressable, or when it is something non-constant (location description, reference, ...). 2024-03-01 Jakub Jelinek <jakub@redhat.com> PR debug/114015 * dwarf2out.cc (should_move_die_to_comdat): Return false for aggregates without DW_AT_byte_size attribute or with non-constant DW_AT_byte_size. * gcc.dg/debug/dwarf2/pr114015.c: New test.
-rw-r--r--gcc/dwarf2out.cc9
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr114015.c14
2 files changed, 23 insertions, 0 deletions
diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 5d64100b95c..03d73f9eecd 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -8215,6 +8215,15 @@ should_move_die_to_comdat (dw_die_ref die)
|| is_nested_in_subprogram (die)
|| contains_subprogram_definition (die))
return false;
+ if (die->die_tag != DW_TAG_enumeration_type)
+ {
+ /* Don't move non-constant size aggregates. */
+ dw_attr_node *sz = get_AT (die, DW_AT_byte_size);
+ if (sz == NULL
+ || (AT_class (sz) != dw_val_class_unsigned_const
+ && AT_class (sz) != dw_val_class_unsigned_const_implicit))
+ return false;
+ }
return true;
case DW_TAG_array_type:
case DW_TAG_interface_type:
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr114015.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr114015.c
new file mode 100644
index 00000000000..a184ab5d392
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr114015.c
@@ -0,0 +1,14 @@
+/* PR debug/114015 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-g -fvar-tracking-assignments -fdebug-types-section -w" } */
+
+#if __BITINT_MAXWIDTH__ >= 236
+typedef _BitInt(236) B;
+#else
+typedef _BitInt(63) B;
+#endif
+
+int
+foo (B n, struct { char a[n]; } o)
+{
+}