X-Git-Url: https://pd.if.org/git/?p=lice;a=blobdiff_plain;f=tests%2Fstruct.c;fp=tests%2Fstruct.c;h=751949283e91c98bfb0400c71a2988e1d1cbc1cb;hp=0000000000000000000000000000000000000000;hb=b6a50b8be3d6a2e2d6624983f6bf1bf0c9f6802a;hpb=946bdbe1d5dd89ab671391fbe429a1c2c48ecaa7 diff --git a/tests/struct.c b/tests/struct.c new file mode 100644 index 0000000..7519492 --- /dev/null +++ b/tests/struct.c @@ -0,0 +1,296 @@ +// structures + +struct A { + int a; + struct { + char b; + int c; + } y; +} A; + +struct B { + int a; +} B; + +struct C { + int a; + int b; +} C; + +int main(void) { + struct { + int a; + } a; + a.a = 1024; + expecti(a.a, 1024); + + struct { + int a; + int b; + } b; + b.a = 1024; + b.b = 2048; + expecti(b.a, 1024); + expecti(b.b, 2048); + + struct { + int a; + struct { + char b; + int c; + } b; + } c; + c.a = 1024; + c.b.b = 32; + c.b.c = 2048; + expecti(c.a, 1024); + expecti(c.b.b, 32); + expecti(c.b.c, 2048); + + struct name1 { + int a; + struct { + char b; + int c; + } b; + }; + struct name1 d; + d.a = 16; + d.b.b = 32; + d.b.c = 64; + expecti(d.a, 16); + expecti(d.b.b, 32); + expecti(d.b.c, 64); + + struct name2 { + int a; + int b; + } e; + struct name2 *f = &e; + + // obj->ptr + e.a = 128; + expecti((*f).a, 128); + + // ptr->obj + (*f).a = 256; + expecti(e.a, 256); + + // again + e.b = 64; + expecti((*f).b, 64); + + (*f).b = 128; + expecti(e.b, 128); + + // over read? + struct { + int a[3]; + int b[3]; + } g; + g.a[0] = 1024; + g.b[1] = 2048; + expecti(g.a[0], 1024); + expecti(g.b[1], 2048); + expecti(g.a[4], 2048); // &g.a[4] == &g.b[0] + + A.a = 64; + A.y.b = 65; + A.y.c = 256; + expecti(A.a, 64); + expecti(A.y.b, 65); + expecti(A.y.c, 256); + + struct B *h = &B; + B.a = 128; + expecti((*h).a, 128); + expecti(B.a, 128); + expecti(h->a, 128); + + h->a = 256; + expecti((*h).a, 256); + expecti(B.a, 256); + expecti(h->a, 256); + + struct C i[3]; + i[0].a = 32; + expecti(i[0].a, 32); + i[0].b = 64; + expecti(i[0].b, 64); + i[1].b = 128; + expecti(i[1].b, 128); + int *j = i; + expecti(j[3], 128); // &j[3] == &i[1].b + + struct { char c; } k = { 'a' }; + expecti(k.c, 'a'); + + struct { int a[3]; } l = { { 1, 2, 3 } }; + expecti(l.a[0], 1); + expecti(l.a[1], 2); + expecti(l.a[2], 3); + + // unnamed shit + struct { + union { + struct { + int x; + int y; + }; + struct { + char c[8]; + }; + }; + } m; + m.x = 10; + m.y = 20; + expecti(m.c[0], 10); + expecti(m.c[4], 20); + + // structure copy via assignment + struct { + int a; + int b; + int c; + } X, Y, Z; + X.a = 8; + X.b = 16; + X.c = 32; + Y = X; + Z.a = 64; + Z.b = 128; + Z.c = 256; + expecti(Y.a, 8); + expecti(Y.b, 16); + expecti(Y.c, 32); + Y = Z; + expecti(Y.a, 64); + expecti(Y.b, 128); + expecti(Y.c, 256); + + // arrows + struct cell { + int value; + struct cell *next; + }; + struct cell aa = { 10, 0 }; + struct cell bb = { 20, &aa }; + struct cell cc = { 30, &bb }; + struct cell *dd = &cc; + + expecti(cc.value, 30); + expecti(dd->value, 30); + expecti(dd->next->value, 20); + expecti(dd->next->next->value, 10); + + dd->value = 16; + dd->next->value = 32; + dd->next->next->value = 64; + expecti(dd->value, 16); + expecti(dd->next->value, 32); + expecti(dd->next->next->value, 64); + + // addressing + struct super { + int a; + struct { + int b; + } y; + } poke = { 99, 100 }; + + int *poke1 = &poke.a; + int *poke2 = &poke.y.b; + + expecti(*poke1, 99); + expecti(*poke2, 100); + expecti(*&poke.a, 99); + expecti(*&poke.y.b, 100); + + struct super *inward = &poke; + int *poke3 = &inward->a; + int *poke4 = &inward->y.b; + + expecti(*poke3, 99); + expecti(*poke4, 100); + expecti(*&inward->a, 99); + expecti(*&inward->y.b, 100); + + // incomplete in the opposite direction + struct incomplete1; + struct incomplete2 { + struct incomplete1 *next; + }; + struct incomplete1 { + int value; + }; + + struct incomplete1 in1 = { 3 }; + struct incomplete2 in2 = { &in1 }; + + expecti(in2.next->value, 3); + + struct { + int x; + } __a = { + 1024 + }, *__b = &__a; + int *__c = &__b->x; + + expecti(*__c, 1024); + + + // bit fields + union { + int i; + struct { + int a: 5; + int b: 5; + }; + } bitfield; + bitfield.i = 0; + bitfield.a = 20; + bitfield.b = 15; + expecti(bitfield.i, 500); // (15 << 5) + 20 == 500 + + struct { + char a:4; + char b:4; + } bitfield2 = { 5, 10 }; + + expecti(bitfield2.a, 5); + expecti(bitfield2.b, 10); + + union { + int a: 10; + char b: 5; + char c: 5; + } bitfield3; + + bitfield3.a = 2; + expecti(bitfield3.a, 2); + expecti(bitfield3.b, 2); + expecti(bitfield3.c, 2); + + struct __empty {}; + expecti(sizeof(struct __empty), 0); + + // FAMS + struct __fam0 { int a, b[]; }; + struct __fam1 { int a, b[0]; }; + + expecti(sizeof(struct __fam0), 4); + expecti(sizeof(struct __fam1), 4); + + struct __gccfam { int a[0]; }; + expecti(sizeof(struct __gccfam), 0); + + struct __famoverwrite { int a, b[]; }; + struct __famoverwrite OV = { 1, 2, 3, 4, 5 }; + + expecti(OV.b[0], 2); + expecti(OV.b[1], 3); + expecti(OV.b[2], 4); + expecti(OV.b[3], 5); + + return 0; +}