1 /* bf-ms-layout.c */
2
3 /* Test for MS bitfield layout */
4 /* Adapted from Donn Terry <donnte@microsoft.com> testcase
5 posted to GCC-patches
6 http://gcc.gnu.org/ml/gcc-patches/2000-08/msg00577.html */
7
8 /* { dg-do run { target i?86-*-* x86_64-*-* } } */
9 /* { dg-options "-D_TEST_MS_LAYOUT" } */
10 /* This test uses the attribute instead of the command line option. */
11
12 #include <stddef.h>
13 #include <string.h>
14
15 extern void abort();
16
17 #pragma pack(8)
18
19 #ifdef __GNUC__
20 #define ATTR __attribute__ ((ms_struct))
21 #endif
22
23 struct one {
24 int d;
25 unsigned char a;
26 unsigned short b:7;
27 char c;
28 } ATTR;
29
30 struct two {
31 int d;
32 unsigned char a;
33 unsigned int b:7;
34 char c;
35 } ATTR;
36
37 struct three {
38 short d;
39 unsigned short a:3;
40 unsigned short b:9;
41 unsigned char c:7;
42 } ATTR;
43
44
45 /* Bitfields of size 0 have some truly odd behaviors. */
46
47 struct four {
48 unsigned short a:3;
49 unsigned short b:9;
50 unsigned int :0; /* forces struct alignment to int */
51 unsigned char c:7;
52 } ATTR;
53
54 struct five {
55 char a;
56 int :0; /* ignored; prior field is not a bitfield. */
57 char b;
58 char c;
59 } ATTR;
60
61 struct six {
62 char a :8;
63 int :0; /* not ignored; prior field IS a bitfield, causes
64 struct alignment as well. */
65 char b;
66 char c;
67 } ATTR;
68
69 struct seven {
70 char a:8;
71 char :0;
72 int :0; /* Ignored; prior field is zero size bitfield. */
73 char b;
74 char c;
75 } ATTR;
76
77 struct eight { /* ms size 4 */
78 short b:3;
79 char c;
80 } ATTR;
81
82 #ifdef _MSC_VER
83 #define LONGLONG __int64
84 #else
85 #define LONGLONG long long
86 #endif
87
88 union nine { /* ms size 8 */
89 LONGLONG a:3;
90 char c;
91 } ATTR;
92
93 struct ten { /* ms size 16 */
94 LONGLONG a:3;
95 LONGLONG b:3;
96 char c;
97 } ATTR;
98
99
100 #define val(s,f) (s.f)
101
102 #define check_struct(_X) \
103 { \
104 if (sizeof (struct _X) != exp_sizeof_##_X ) \
105 abort(); \
106 memcpy(&test_##_X, filler, sizeof(test_##_X));\
107 if (val(test_##_X,c) != exp_##_X##_c) \
108 abort(); \
109 }
110
111 #define check_union(_X) \
112 { \
113 if (sizeof (union _X) != exp_sizeof_##_X ) \
114 abort(); \
115 memcpy(&test_##_X, filler, sizeof(test_##_X));\
116 if (val(test_##_X,c) != exp_##_X##_c) \
117 abort(); \
118 }
119
120 #define check_struct_size(_X) \
121 { \
122 if (sizeof (struct _X) != exp_sizeof_##_X ) \
123 abort(); \
124 }
125
126 #define check_struct_off(_X) \
127 { \
128 memcpy(&test_##_X, filler, sizeof(test_##_X));\
129 if (val(test_##_X,c) != exp_##_X##_c) \
130 abort(); \
131 }
132
133 #define check_union_size(_X) \
134 { \
135 if (sizeof (union _X) != exp_sizeof_##_X ) \
136 abort(); \
137 }
138
139 #define check_union_off(_X) \
140 { \
141 memcpy(&test_##_X, filler, sizeof(test_##_X));\
142 if (val(test_##_X,c) != exp_##_X##_c) \
143 abort(); \
144 }
145
main()146 int main(){
147
148 unsigned char filler[16];
149 struct one test_one;
150 struct two test_two;
151 struct three test_three;
152 struct four test_four;
153 struct five test_five;
154 struct six test_six;
155 struct seven test_seven;
156 struct eight test_eight;
157 union nine test_nine;
158 struct ten test_ten;
159
160 #if defined (_TEST_MS_LAYOUT) || defined (_MSC_VER)
161 size_t exp_sizeof_one = 12;
162 size_t exp_sizeof_two = 16;
163 size_t exp_sizeof_three =6;
164 size_t exp_sizeof_four = 8;
165 size_t exp_sizeof_five = 3;
166 size_t exp_sizeof_six = 8;
167 size_t exp_sizeof_seven = 3;
168 size_t exp_sizeof_eight = 4;
169 size_t exp_sizeof_nine = 8;
170 size_t exp_sizeof_ten = 16;
171
172 unsigned char exp_one_c = 8;
173 unsigned char exp_two_c = 12;
174 unsigned char exp_three_c = 4;
175 unsigned char exp_four_c = 4;
176 char exp_five_c = 2;
177 char exp_six_c = 5;
178 char exp_seven_c = 2;
179 char exp_eight_c = 2;
180 char exp_nine_c = 0;
181 char exp_ten_c = 8;
182
183 #else /* testing -mno-ms-bitfields */
184
185 size_t exp_sizeof_one = 8;
186 size_t exp_sizeof_two = 8;
187 size_t exp_sizeof_three = 6;
188 size_t exp_sizeof_four = 6;
189 size_t exp_sizeof_five = 6;
190 size_t exp_sizeof_six = 6;
191 size_t exp_sizeof_seven = 6;
192 size_t exp_sizeof_eight = 2;
193 size_t exp_sizeof_nine = 8;
194 size_t exp_sizeof_ten = 8;
195
196 unsigned short exp_one_c = 6;
197 unsigned int exp_two_c = 6;
198 unsigned char exp_three_c = 64;
199 unsigned char exp_four_c = 4;
200 char exp_five_c = 5;
201 char exp_six_c = 5;
202 char exp_seven_c = 5;
203 char exp_eight_c = 1;
204 char exp_nine_c = 0;
205 char exp_ten_c = 1;
206
207 #endif
208
209 unsigned char i;
210 for ( i = 0; i < 16; i++ )
211 filler[i] = i;
212
213 check_struct_off (one);
214 check_struct_off (two);
215 check_struct_off (three);
216 check_struct_off (four);
217 check_struct_off (five);
218 check_struct_off (six);
219 check_struct_off (seven);
220 check_struct_off (eight);
221 check_union_off (nine);
222 check_struct_off (ten);
223
224 check_struct_size (one);
225 check_struct_size (two);
226 check_struct_size (three);
227 check_struct_size (four);
228 check_struct_size (five);
229 check_struct_size (six);
230 check_struct_size (seven);
231 check_struct_size (eight);
232 check_union_size (nine);
233 check_struct_size (ten);
234
235 return 0;
236 };
237