]> pd.if.org Git - lice/blobdiff - tests/struct.c
autocommit for files dated 2014-11-17 20:13:38
[lice] / tests / struct.c
diff --git a/tests/struct.c b/tests/struct.c
new file mode 100644 (file)
index 0000000..7519492
--- /dev/null
@@ -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;
+}