CE-Programming / toolchain

Toolchain and libraries for C/C++ programming on the TI-84+ CE calculator series
https://ce-programming.github.io/toolchain/index.html
GNU Lesser General Public License v3.0
528 stars 53 forks source link

Possible Toolchain (Compiler?) Bug #521

Closed KermMartian closed 4 days ago

KermMartian commented 4 days ago

I have a data structure; let's call it Foo:

struct Foo {
    unsigned char flag1;   // offset 0
    char* bar;             // offset 1
    unsigned char flag2;   // offset 4
};

I create a 6-element array of these, and later allocate memory for each of the bar elements: Foo foos[6];. In a loop over an array of 6 pointers pointing to heap-allocated data structures, a dbg_printf() statement as follows emits the following code in the associated .src file:

dbg_printf("1: copying from %zx\n", (size_t)(void*)(*foos)[i].bar);
      ld  hl, (ix - 62)
      push    hl
      ld  hl, _.str.12
      push    hl
      ld  hl, -327680
      push    hl
      call    _sprintf

I verify via memory inspection in CEmu that (ix-62) does indeed contain the address of the relevant bar. But the code for the following C statement uses a different location:

strncpy(baz, (*foos[i]).bar, barLen);
        ld      hl, (ix - 56)
        ld      de, (hl)
        loc     0 184 4
        ld      hl, (ix - 59)
        push    hl
        push    de
        push    bc
        call    _strncpy
        private tmp163

When this code runs, (ix + 6) points to the beginning of the 6-element array foos, and before the first iteration of the loop, this address plus 1 is stored in (ix + 56). Fine, if we step by 5, (ix + 56) should point to each bar member of each successive foos element. But the loop actually adds 30, not the expect 5:

        ld      iy, (ix - 56)
        lea     iy, iy + 30
        ld      (ix - 56), iy

I'll see if I can't turn this into a MWE.

mateoconlechuga commented 4 days ago

30 = 6 5, `(foos[i])is not the same thing as(*foos)[i]`.

KermMartian commented 4 days ago

Thank you.