]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
dwarf2out: Don't move variable sized aggregates to comdat [PR114015]
authorJakub Jelinek <jakub@redhat.com>
Fri, 1 Mar 2024 13:57:15 +0000 (14:57 +0100)
committerJakub Jelinek <jakub@redhat.com>
Fri, 1 Mar 2024 13:57:15 +0000 (14:57 +0100)
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.

gcc/dwarf2out.cc
gcc/testsuite/gcc.dg/debug/dwarf2/pr114015.c [new file with mode: 0644]

index 5d64100b95c56ac9b76718fa51a649fe0f722144..03d73f9eecda5aa52e268ff4e368545715b5e0d8 100644 (file)
@@ -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 (file)
index 0000000..a184ab5
--- /dev/null
@@ -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)
+{
+}