1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
/*
!!DESCRIPTION!! Make sure that the fields of anonymous structs/unions can be reached properly.
!!ORIGIN!! cc65 regression tests
!!LICENCE!! Public Domain
!!AUTHOR!! Greg King
*/
#include <stddef.h>
#include <stdio.h>
static unsigned char fails = 0;
typedef struct {
short s1;
struct {
char c1;
int i1;
long l1;
};
char c2;
} s1_t;
typedef struct {
char c2;
union {
int i1;
char c1;
long l1;
};
short s1;
} s2_t;
typedef union {
short s1;
struct {
int i1;
long l1;
char c1;
};
char c2;
} u1_t;
typedef union {
short s1;
union {
long l1;
char c1;
int i1;
};
char c2;
} u2_t;
typedef struct {
union {
short s1;
struct {
int i1;
long l1;
char c1;
};
char c2;
};
short s2;
} s3_t;
static s1_t s1;
static s2_t s2;
static u1_t u1;
static u2_t u2;
static long l2;
static int i2;
/* We use "variables" in the comparisons, so that we can avoid "constant
** comparison" and "Unreachable code" warnings (the second one currently
** can't be suppressed).
*/
static size_t const zero = 0;
static size_t const one = 1;
static size_t const three = 3;
static size_t const five = 5;
static size_t const six = 6;
static size_t const seven = 7;
static size_t const nine = 9;
int main(void)
{
/* Can cc65 see the names of members of anonymous structs/unions? */
l2 = s1.l1;
l2 = s2.l1;
l2 = u1.l1;
l2 = u2.l1;
i2 = s1.c1;
i2 = s1.c2;
i2 = s2.c1;
i2 = s2.c2;
i2 = u1.c1;
i2 = u1.c2;
i2 = u2.c1;
i2 = u2.c2;
/* Does cc65 use the correct offsets of
** the members of anonymous structs/unions?
*/
if (offsetof(s1_t, i1) != three) {
printf("The offset of s1.i1 is %u; it should be 3.\n", offsetof(s1_t, i1));
++fails;
}
if (offsetof(s2_t, l1) != one) {
printf("The offset of s2.l1 is %u; it should be 1.\n", offsetof(s2_t, l1));
++fails;
}
if (offsetof(u1_t, c1) != six) {
printf("The offset of u1.c1 is %u; it should be 6.\n", offsetof(u1_t, c1));
++fails;
}
if (offsetof(u2_t, i1) != zero) {
printf("The offset of u2.i1 is %u; it should be 0.\n", offsetof(u2_t, i1));
++fails;
}
/* Does cc65 use the correct offset of a member
** that's later than an anonymous struct/union?
*/
if (offsetof(s1_t, c2) != nine) {
printf("The offset of s1.c2 is %u; it should be 9.\n", offsetof(s1_t, c2));
++fails;
}
if (offsetof(s2_t, s1) != five) {
printf("The offset of s2.s1 is %u; it should be 5.\n", offsetof(s2_t, s1));
++fails;
}
if (offsetof(u1_t, c2) != zero) {
printf("The offset of u1.c2 is %u; it should be 0.\n", offsetof(u1_t, c2));
++fails;
}
if (offsetof(u2_t, c2) != zero) {
printf("The offset of u2.c2 is %u; it should be 0.\n", offsetof(u2_t, c2));
++fails;
}
if (offsetof(s3_t, s2) != seven) {
printf("The offset of s3.s2 is %u; it should be 7.\n", offsetof(s3_t, s2));
++fails;
}
return fails;
}
|