When translating type bit sizes from DWARF, ctf_die_bitsize was
using uint32_t.  For extremely large struct types, the bit size may be
larger than 32-bits and hence truncated, which caused incorrect encoding
for these huge structs rather than properly using CTF's large type size
encoding.  Switching to uHWI avoids the truncation so these struct types
are properly handled by the existing code.

Tested on x86_64-pc-linux-gnu.

        PR debug/121411

gcc/

        * dwarf2ctf.cc (ctf_die_bitsize): Return unsigned HOST_WIDE_INT
        instead of uint32_t.
        (gen_ctf_base_type, gen_ctf_sou_type, gen_ctf_enumeration_type):
        Adapt accordingly.

gcc/testsuite/

        * gcc.dg/debug/ctf/ctf-struct-3.c: New test.
---
 gcc/dwarf2ctf.cc                              | 14 +++++++-----
 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-3.c | 22 +++++++++++++++++++
 2 files changed, 30 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-3.c

diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index f8b305b6c4a..f6d4963726f 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -199,7 +199,7 @@ gen_ctf_unknown_type (ctf_container_ref ctfc)
    If no DW_AT_byte_size nor DW_AT_bit_size are defined, this function
    returns 0.  */
 
-static uint32_t
+static unsigned HOST_WIDE_INT
 ctf_die_bitsize (dw_die_ref die)
 {
   dw_attr_node *attr_byte_size = get_AT (die, DW_AT_byte_size);
@@ -225,7 +225,9 @@ gen_ctf_base_type (ctf_container_ref ctfc, dw_die_ref type)
   ctf_encoding_t ctf_encoding = {0, 0, 0};
 
   unsigned int encoding = get_AT_unsigned (type, DW_AT_encoding);
-  unsigned int bit_size = ctf_die_bitsize (type);
+  /* Bit size for base types handled here should never be very large
+     (BITSIZE_MAXWIDTH at the upper end).  */
+  unsigned int bit_size = (unsigned int) ctf_die_bitsize (type);
   const char * name_string = get_AT_string (type, DW_AT_name);
 
   switch (encoding)
@@ -514,7 +516,7 @@ gen_ctf_modifier_type (ctf_container_ref ctfc, dw_die_ref 
modifier)
 static ctf_dtdef_ref
 gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, uint32_t kind)
 {
-  uint32_t bit_size = ctf_die_bitsize (sou);
+  unsigned HOST_WIDE_INT bit_size = ctf_die_bitsize (sou);
   int declaration_p = get_AT_flag (sou, DW_AT_declaration);
   const char *sou_name = get_AT_string (sou, DW_AT_name);
 
@@ -564,7 +566,7 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, 
uint32_t kind)
            {
              dw_attr_node *attr;
              HOST_WIDE_INT bitpos = 0;
-             HOST_WIDE_INT bitsize = ctf_die_bitsize (c);
+             unsigned HOST_WIDE_INT bitsize = ctf_die_bitsize (c);
              HOST_WIDE_INT bit_offset;
 
              /* The bit offset is given in bits and it may be
@@ -581,7 +583,7 @@ gen_ctf_sou_type (ctf_container_ref ctfc, dw_die_ref sou, 
uint32_t kind)
                    bitpos = field_location + bit_offset;
                  else
                    {
-                     HOST_WIDE_INT bit_size;
+                     unsigned HOST_WIDE_INT bit_size;
 
                      attr = get_AT (c, DW_AT_byte_size);
                      if (attr)
@@ -730,7 +732,7 @@ static ctf_dtdef_ref
 gen_ctf_enumeration_type (ctf_container_ref ctfc, dw_die_ref enumeration)
 {
   const char *enum_name = get_AT_string (enumeration, DW_AT_name);
-  unsigned int bit_size = ctf_die_bitsize (enumeration);
+  unsigned HOST_WIDE_INT bit_size = ctf_die_bitsize (enumeration);
   unsigned int signedness = get_AT_unsigned (enumeration, DW_AT_encoding);
   int declaration_p = get_AT_flag (enumeration, DW_AT_declaration);
 
diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-3.c 
b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-3.c
new file mode 100644
index 00000000000..8a12764f249
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-struct-3.c
@@ -0,0 +1,22 @@
+/* PR debug/121411.
+   Test for compilation of very large struct types.
+   The ctt_size for the struct shall encode CTF_LSIZE_SENT to indicate the
+   large struct encoding is used.  */
+/* { dg-do compile } */
+/* { dg-options "-O0 -gctf -dA" } */
+
+struct huge
+{
+  unsigned char a1[0xffffffff];
+  unsigned char a2[0xffffffff];
+  char x;
+  char y;
+  char z;
+};
+
+struct huge v;
+
+/* { dg-final { scan-assembler-times "0x1a000005\[\t \]+\[^\n\]*ctt_info" 1 } 
} */
+/* { dg-final { scan-assembler-times "0xffffffff\[\t \]+\[^\n\]*ctt_size" 1 } 
} */
+/* { dg-final { scan-assembler-times "0x2\[\t \]+\[^\n\]*ctt_lsizehi" 1 } } */
+/* { dg-final { scan-assembler-times "ctt_lsizelo" 1 } } */
-- 
2.47.2

Reply via email to