PR debug/112878: ICE: in ctf_add_slice, at ctfc.cc:499 with
_BitInt > 255 in a struct and -gctf1
The CTF generation in GCC does not have a mechanism to roll-back an
already added type. In this testcase presented in the PR, we hit a
representation limit in CTF slices (for a member of a struct) and ICE,
after the type for struct (CTF_K_STRUCT) has already been added to the
container.
To exit gracefully instead, we now check for both the offset and size of
the bitfield to be explicitly <= 255. If the check fails, we emit the
member with type CTF_K_UNKNOWN. Note that, the value 255 stems from the
existing binutils libctf checks which were motivated to guard against
malformed inputs.
Although it is not accurate to say that this is a CTF representation
limit, mark the code with TBD_CTF_REPRESENTATION_LIMIT for now so that
this can be taken care of with the next format version bump, when
libctf's checks for the slice data can be lifted as well.
gcc/ChangeLog:
PR debug/112878
* dwarf2ctf.cc (gen_ctf_sou_type): Check for conditions before
call to ctf_add_slice. Use CTF_K_UNKNOWN type if fail.
gcc/testsuite/ChangeLog:
PR debug/112878
* gcc.dg/debug/ctf/ctf-bitfields-5.c: New test.
if (attr)
bitpos += AT_unsigned (attr);
- field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT,
- field_type_id,
- bitpos - field_location,
- bitsize,
- c);
+ /* This is not precisely a TBD_CTF_REPRESENTATION_LIMIT, but
+ surely something to look at for the next format version bump
+ for CTF. */
+ if (bitsize <= 255 && (bitpos - field_location) <= 255)
+ field_type_id = ctf_add_slice (ctfc, CTF_ADD_NONROOT,
+ field_type_id,
+ bitpos - field_location,
+ bitsize, c);
+ else
+ field_type_id = gen_ctf_unknown_type (ctfc);
}
/* Add the field type to the struct or union type. */
--- /dev/null
+/* Bitfield where the bit offset is > 255 is not allowed in CTF.
+
+ PR debug/112878.
+ This testcase is to ensure graceful handling. No slices are expected. */
+
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-O0 -gctf -dA" } */
+
+/* No slices are expected, but a struct with one member is expected.
+ CTF_K_UNKNOWN is also expected. */
+/* { dg-final { scan-assembler-times "cts_type" 0 } } */
+/* { dg-final { scan-assembler-times "\[\t \]0x1a000001\[\t \]+\[^\n\]*ctt_info" 1 } } */
+/* { dg-final { scan-assembler-times "ascii \"unknown.0\"\[\t \]+\[^\n\]*ctf_string" 1 } } */
+
+struct {
+ _BitInt(282) a : 280;
+} b;