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