gdb: Make the builtin "boolean" type an unsigned type
authorShahab Vahedi <shahab@synopsys.com>
Mon, 19 Jul 2021 14:13:47 +0000 (16:13 +0200)
committerShahab Vahedi <shahab@synopsys.com>
Mon, 2 Aug 2021 11:00:01 +0000 (13:00 +0200)
commit91254b918f1b35359d44b567a15013c42a931460
tree87f915fff7d9fbdbe26e6f7014195b3c4bf36b28
parent7d315ef225c1553d30180fd5690c688c09151c52
gdb: Make the builtin "boolean" type an unsigned type

When printing the fields of a register that is of a custom struct type,
the "unpack_bits_as_long ()" function is used:

    do_val_print (...)
      cp_print_value_fields (...)
        value_field_bitfield (...)
          unpack_value_bitfield (...)
            unpack_bits_as_long (...)

This function may sign-extend the extracted field while returning it:

    val >>= lsbcount;

    if (...)
      {
        valmask = (((ULONGEST) 1) << bitsize) - 1;
        val &= valmask;
        if (!field_type->is_unsigned ())
     if (val & (valmask ^ (valmask >> 1)))
         val |= ~valmask;
      }

    return val;

lsbcount:   Number of lower bits to get rid of.
bitsize:    The bit length of the field to be extracted.
val:        The register value.
field_type: The type of field that is being handled.

While the logic here is correct, there is a problem when it is
handling "field_type"s of "boolean".  Those types are NOT marked
as "unsigned" and therefore they end up being sign extended.
Although this is not a problem for "false" (0), it definitely
causes trouble for "true".

This patch constructs the builtin boolean type as such that it is
marked as an "unsigned" entity.

The issue tackled here was first encountered for arc-elf32 target
running on an x86_64 machine.  The unit-test introduced in this change
has passed for all the targets (--enable-targets=all) running on the
same x86_64 host.

Fixes: https://sourceware.org/PR28104
gdb/cp-valprint.c
gdb/gdbtypes.c