boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

333-struct-assign-big.c (2343B)


      1 /* Struct/union assignment must memcpy the whole aggregate, not just
      2  * the first 8 bytes. cg-assign's scalar path emitted one 8-byte
      3  * load + store, dropping every field at offset >= 8 — which silently
      4  * broke vswap() in tcc.flat.c (SValue is 64 bytes), surfacing as the
      5  * vtop[-1].r < VT_CONST assertion in arm64-gen.c during tcc-cc.
      6  *
      7  * Exercises:
      8  *   - direct struct lvalue = lvalue assignment
      9  *   - assignment through pointer indices (vtop[0] = vtop[-1] shape)
     10  *   - tmp = src; src = dst; dst = tmp three-way swap
     11  *   - fields at offsets 0, 4, 8, 16+ — including a sub-word field
     12  *     past offset 8 (mirrors SValue.r at offset 16)
     13  */
     14 
     15 struct Big {
     16     int a;
     17     int b;
     18     unsigned short r;
     19     unsigned short r2;
     20     long c[2];
     21     void *sym;
     22 };
     23 
     24 static struct Big buf[4];
     25 
     26 static void swap2(struct Big *p) {
     27     struct Big tmp;
     28     tmp = p[0];
     29     p[0] = p[-1];
     30     p[-1] = tmp;
     31 }
     32 
     33 int main(int argc, char **argv) {
     34     /* Direct assignment between two named struct lvalues. */
     35     struct Big x;
     36     struct Big y;
     37     x.a = 0xA1; x.b = 0xA2; x.r = 0xA3; x.r2 = 0xA4;
     38     x.c[0] = 0xA5; x.c[1] = 0xA6; x.sym = (void *)0xA7;
     39     y = x;
     40     if (y.a  != 0xA1) return 1;
     41     if (y.b  != 0xA2) return 2;
     42     if (y.r  != 0xA3) return 3;
     43     if (y.r2 != 0xA4) return 4;
     44     if (y.c[0] != 0xA5) return 5;
     45     if (y.c[1] != 0xA6) return 6;
     46     if (y.sym  != (void *)0xA7) return 7;
     47 
     48     /* Pointer-indexed struct swap (tcc's vswap pattern). */
     49     buf[0].a = 0x01; buf[0].b = 0x02; buf[0].r = 0x03; buf[0].r2 = 0x04;
     50     buf[0].c[0] = 0x05; buf[0].c[1] = 0x06; buf[0].sym = (void *)0x07;
     51     buf[1].a = 0x11; buf[1].b = 0x12; buf[1].r = 0x13; buf[1].r2 = 0x14;
     52     buf[1].c[0] = 0x15; buf[1].c[1] = 0x16; buf[1].sym = (void *)0x17;
     53     swap2(&buf[1]);
     54     if (buf[0].a  != 0x11) return 11;
     55     if (buf[0].b  != 0x12) return 12;
     56     if (buf[0].r  != 0x13) return 13;
     57     if (buf[0].r2 != 0x14) return 14;
     58     if (buf[0].c[0] != 0x15) return 15;
     59     if (buf[0].c[1] != 0x16) return 16;
     60     if (buf[0].sym  != (void *)0x17) return 17;
     61     if (buf[1].a  != 0x01) return 21;
     62     if (buf[1].b  != 0x02) return 22;
     63     if (buf[1].r  != 0x03) return 23;
     64     if (buf[1].r2 != 0x04) return 24;
     65     if (buf[1].c[0] != 0x05) return 25;
     66     if (buf[1].c[1] != 0x06) return 26;
     67     if (buf[1].sym  != (void *)0x07) return 27;
     68 
     69     return 0;
     70 }