Menu

#4053 Codegen error for SM83/GBZ80 array index with bit packed bool in struct

closed-fixed
sm83 (9) z80 (21)
other
5
1 day ago
6 days ago
bbbbbr
No
bin/sdcc -v                                                          
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/r4k/r5k/r6k/sm83/tlcs90/ez80/z80n/r800/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/f8/f8l TD- 4.6.2 #16701 (Linux)

Getting a codegen error on sm83/gbz80 for array indexing with a bool that is bit packed in a struct. Instead of generating a lookup for [1] with true it generates [-1].

Building with:

sdcc -msm83 --no-std-crt0 --fsigned-char --use-stdout -Wa-pogn -c main.c -o main.o

Test case:

#define true ((_Bool)+1)
#define false ((_Bool)+0)
#define bool _Bool
#define __bool_true_false_are_defined 1

#define ICON_CBX            "\x18"
#define ICON_CBX_CHECKED    "\x19"

typedef struct test_options_t {
    bool print_fast                 : 1;
    bool fancy_sgb_border           : 1;
    bool show_grid                  : 1;
    bool save_confirm               : 1;
    bool ir_remote_shutter          : 1;
    bool boot_to_camera_mode        : 1;
    bool double_speed               : 1;
    unsigned char shutter_timer;
} test_options_t;

test_options_t test_state;
unsigned char text_buffer_test[4];
const unsigned char * const checkbox[] = {ICON_CBX, ICON_CBX_CHECKED};

void test_array_index_bitpacked_struct_bool(void) {

        unsigned char * temp =  checkbox[test_state.save_confirm];
        *text_buffer_test = *temp;
}

void main(void) {
    test_state.save_confirm = true;
    test_array_index_bitpacked_struct_bool();

    test_state.save_confirm = false;
    test_array_index_bitpacked_struct_bool();
}

The relevant output (sm83, but the equivalent z80 output has a similar issue):

_test_array_index_bitpacked_struct_bool::
;main.c:28: unsigned char * temp =  checkbox[test_state.save_confirm];
    ld  bc, #_checkbox+0
    ld  a, (#_test_state + 0)

    swap    a
    rlca
    rra
    sbc a, a
    ld  l, a
    rlca
    sbc a, a
    ld  h, a

    add hl, hl  <-- This ends up being 0xFFFE
    add hl, bc  <-- Indexing to [-1] instead of [1] here
    ld  a, (hl+)

Given what it is trying to do, the intended output for the calculation should maybe look more like:

    swap    a
    sla     a
    ld      h, a
    rlca
    ld  h, a

For reference, here is the SDCC ~15267 output that produces a correct index:

    ld  bc, #_checkbox+0
    ld  a, (#_test_state + 0)
    swap    a
    rlca
    and a, #0x01
    ld  l, a
    ld  h, #0x00
    add hl, hl
    add hl, bc
    ld  a, (hl+)

Discussion

  • Tony Pavlov

    Tony Pavlov - 5 days ago

    yes, this bug is pretty annoying :(

     
  • Benedikt Freisen

    This could potentially be a side effect of [r16144] which intended to make plain int bit-fields signed to mimic GCC behavior.
    The change has no special case for bool.

     

    Related

    Commit: [r16144]

    • Philipp Klaus Krause

      The change wasn't to mimic GCC; it was because there is simply no reasonable way to make unsigned-by-default int bit-fields work with the C standard. See C defect report 315, C issue 1007, and in particular the discussion at the August 2025 WG14 meeting in Brno (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3815.htm).

      Despite the C standard at first sight allowing plain int to be unsigned, trying to actually do so runs into serious issues in particular wrt. typedef and typeof.

       
      • Maarten Brock

        Maarten Brock - 2 days ago

        But how does that relate to bool?

         
        • Philipp Klaus Krause

          That was a change in handling signedness of int bit-fields, this bug is about z80 codegen incorrectly treating bool bit-fields as signed. Might be related or not (not worth looking into more, I'll have a fix later today without looking into the history of this issue anyway).

           
  • Philipp Klaus Krause

    I can reproduce the issue on my Debian GNU/Linux amd64 testing system. Looks like all z80-related ports are affected, but no other ports.

     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
    • assigned_to: Philipp Klaus Krause
     
  • Philipp Klaus Krause

    Fixed in [r16777].

     

    Related

    Commit: [r16777]

    • bbbbbr

      bbbbbr - 1 day ago

      Thanks, fix looks good here

       

Log in to post a comment.