Skip to content

Commit 1d93fa1

Browse files
author
Daniel Kroening
committed
Visual Studio packs bit-fields differently
1 parent 19cfa50 commit 1d93fa1

File tree

7 files changed

+394
-88
lines changed

7 files changed

+394
-88
lines changed

appveyor.yml

-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ test_script:
7070
rmdir /s /q ansi-c\arch_flags_mthumb_good
7171
rmdir /s /q ansi-c\Forward_Declaration2
7272
rmdir /s /q ansi-c\Incomplete_Type1
73-
rmdir /s /q ansi-c\Union_Padding1
7473
rmdir /s /q ansi-c\Universal_characters1
7574
rmdir /s /q ansi-c\gcc_attributes7
7675
rmdir /s /q ansi-c\gcc_version1

buildspec-windows.yml

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ phases:
3434
Remove-Item ansi-c\arch_flags_mthumb_good -Force -Recurse
3535
Remove-Item ansi-c\Forward_Declaration2 -Force -Recurse
3636
Remove-Item ansi-c\Incomplete_Type1 -Force -Recurse
37-
Remove-Item ansi-c\Union_Padding1 -Force -Recurse
3837
Remove-Item ansi-c\gcc_attributes7 -Force -Recurse
3938
Remove-Item ansi-c\gcc_version1 -Force -Recurse
4039
Remove-Item cbmc\Malloc23 -Force -Recurse

regression/ansi-c/Struct_Padding3/main.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ struct my_struct3 {
9999
char ch3;
100100
long long i2; // this should be padded for 8-byte alignment
101101
char ch4;
102-
int bf1:1; // this should not be padded
103-
int bf2:1; // this should not be padded
102+
int bf1 : 1; // MSVC pads this, the gcc/clang do not
103+
int bf2 : 1; // MSVC pads this, the gcc/clang do not
104104
int i3; // this should be padded for 4-byte alignment
105105
};
106106

@@ -110,7 +110,12 @@ STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i1)==4);
110110
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, ch3)==8);
111111
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i2)==16);
112112
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, ch4)==24);
113+
114+
#ifdef _MSC_VER
115+
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i3) == 32);
116+
#else
113117
STATIC_ASSERT(__builtin_offsetof(struct my_struct3, i3)==28);
118+
#endif
114119

115120
int main()
116121
{

regression/ansi-c/Struct_Padding4/main.c

+119-13
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,151 @@ struct Z1
77
int i:3;
88
char ch2;
99
// there is end-of-struct padding because of the int
10-
} z1;
10+
};
11+
12+
STATIC_ASSERT(_Alignof(struct Z1) == _Alignof(int));
13+
14+
#ifdef _MSC_VER
15+
STATIC_ASSERT(sizeof(struct Z1) == 4 + 4 + 4);
16+
#else
17+
STATIC_ASSERT(sizeof(struct Z1) == 1 + 1 + 1 + 1);
18+
#ifdef __GNUC__
19+
STATIC_ASSERT(__builtin_offsetof(struct Z1, ch2) == 2);
20+
#endif
21+
#endif
22+
23+
#pragma pack(push, 1)
24+
struct Z1_packed
25+
{
26+
char ch;
27+
int i : 3;
28+
char ch2;
29+
// there is no end-of-struct padding
30+
};
31+
#pragma pack(pop)
32+
33+
STATIC_ASSERT(_Alignof(struct Z1_packed) == 1);
34+
35+
#ifdef _MSC_VER
36+
STATIC_ASSERT(sizeof(struct Z1_packed) == 1 + 4 + 1);
37+
#else
38+
STATIC_ASSERT(sizeof(struct Z1_packed) == 1 + 1 + 1);
39+
#ifdef __GNUC__
40+
STATIC_ASSERT(__builtin_offsetof(struct Z1_packed, ch2) == 2);
41+
#endif
42+
#endif
1143

1244
struct Z2
1345
{
1446
char ch;
1547
char i:3;
1648
char ch2;
1749
// there is no end-of-struct padding
18-
} z2;
50+
};
51+
52+
STATIC_ASSERT(sizeof(struct Z2) == 1 + 1 + 1);
53+
54+
#pragma pack(push, 1)
55+
struct Z2_packed
56+
{
57+
char ch;
58+
char i : 3;
59+
char ch2;
60+
// there is no end-of-struct padding
61+
};
62+
#pragma pack(pop)
63+
64+
STATIC_ASSERT(sizeof(struct Z2_packed) == 1 + 1 + 1);
1965

2066
struct Z3
2167
{
2268
char ch;
23-
int i:3; // bit-fields do not get padding!
24-
} z3;
69+
int i : 3; // padded by MSVC, not by gcc/clang
70+
};
71+
72+
#ifdef _MSC_VER
73+
STATIC_ASSERT(sizeof(struct Z3) == 4 + 4);
74+
#else
75+
STATIC_ASSERT(sizeof(struct Z3) == 1 + 1 + 2);
76+
#endif
77+
78+
#pragma pack(push, 1)
79+
struct Z3_packed
80+
{
81+
char ch;
82+
int i : 3; // padded by MSVC, not by gcc/clang
83+
};
84+
#pragma pack(pop)
85+
86+
#ifdef _MSC_VER
87+
STATIC_ASSERT(sizeof(struct Z3_packed) == 1 + 4);
88+
#else
89+
STATIC_ASSERT(sizeof(struct Z3_packed) == 1 + 1);
90+
#endif
2591

2692
struct Z4
2793
{
2894
int i;
2995
long long int x; // pads to 8
3096
char ch; // 7 end-of-struct padding
31-
} z4;
97+
};
98+
99+
STATIC_ASSERT(sizeof(struct Z4) == 4 + 4 + 8 + 1 + 7);
100+
101+
#pragma pack(push, 1)
102+
struct Z4_packed
103+
{
104+
int i;
105+
long long int x; // no padding
106+
char ch; // no end-of-struct padding
107+
};
108+
#pragma pack(pop)
109+
110+
STATIC_ASSERT(sizeof(struct Z4_packed) == 4 + 8 + 1);
32111

33112
struct Z5
34113
{
35114
char ch;
36115
long long int x[]; // pads to 8, but has no size
37-
} z5;
116+
};
38117

39-
STATIC_ASSERT(sizeof(struct Z1)==1+1+1+1);
118+
STATIC_ASSERT(sizeof(struct Z5) == 8);
40119

41-
#ifdef __GNUC__
42-
STATIC_ASSERT(__builtin_offsetof(struct Z1, ch2)==2);
120+
#pragma pack(push, 1)
121+
struct Z5_packed
122+
{
123+
char ch;
124+
long long int x[]; // pads to 8, but has no size
125+
};
126+
#pragma pack(pop)
127+
128+
STATIC_ASSERT(sizeof(struct Z5_packed) == 1);
129+
130+
struct Z6
131+
{
132+
char ch;
133+
int i : 16; // padded to int by MSVC, to short by gcc/clang
134+
};
135+
136+
#ifdef _MSC_VER
137+
STATIC_ASSERT(sizeof(struct Z6) == 4 + 4);
138+
#else
139+
STATIC_ASSERT(sizeof(struct Z6) == 1 + 1 + 2);
43140
#endif
44141

45-
STATIC_ASSERT(sizeof(struct Z2)==1+1+1);
46-
STATIC_ASSERT(sizeof(struct Z3)==1+1+2);
47-
STATIC_ASSERT(sizeof(struct Z4)==4+4+8+1+7);
48-
STATIC_ASSERT(sizeof(struct Z5)==8);
142+
#pragma pack(push, 1)
143+
struct Z6_packed
144+
{
145+
char ch;
146+
int i : 16; // padded to int by MSC, but not aligned
147+
};
148+
#pragma pack(pop)
149+
150+
#ifdef _MSC_VER
151+
STATIC_ASSERT(sizeof(struct Z6_packed) == 1 + 4);
152+
#else
153+
STATIC_ASSERT(sizeof(struct Z6_packed) == 1 + 2);
154+
#endif
49155

50156
int main()
51157
{

regression/ansi-c/Struct_Padding5/main.c

+40
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,46 @@ STATIC_ASSERT(sizeof(struct flowi)==8);
2828
STATIC_ASSERT(__builtin_offsetof(struct flowi, flexible)==1);
2929
#endif
3030

31+
// bit-fields are very evil
32+
#pragma pack(push, 1)
33+
struct bit_field0
34+
{
35+
int i : 23;
36+
};
37+
38+
struct bit_field1
39+
{
40+
int i : 1;
41+
unsigned int j : 1;
42+
// in MSC, it matters that the underlying type changes!
43+
short c : 1;
44+
};
45+
46+
struct bit_field2
47+
{
48+
int i : 23;
49+
char ch;
50+
};
51+
#pragma pack(pop)
52+
53+
struct bit_field3
54+
{
55+
int i : 23;
56+
char ch;
57+
};
58+
59+
#ifdef _MSC_VER
60+
STATIC_ASSERT(sizeof(struct bit_field0) == 4);
61+
STATIC_ASSERT(sizeof(struct bit_field1) == 6);
62+
STATIC_ASSERT(sizeof(struct bit_field2) == 5);
63+
STATIC_ASSERT(sizeof(struct bit_field3) == 8);
64+
#else
65+
STATIC_ASSERT(sizeof(struct bit_field0) == 3);
66+
STATIC_ASSERT(sizeof(struct bit_field1) == 1);
67+
STATIC_ASSERT(sizeof(struct bit_field2) == 4);
68+
STATIC_ASSERT(sizeof(struct bit_field3) == 4);
69+
#endif
70+
3171
int main()
3272
{
3373
}

regression/ansi-c/Union_Padding1/main.c

+15-9
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,16 @@ STATIC_ASSERT(sizeof(union some_union3)==sizeof(int));
4141
#ifdef _MSC_VER
4242

4343
// bit-fields are evil
44-
#pragma pack(1)
44+
#pragma pack(push, 1)
4545
union some_union4
4646
{
4747
int i:23;
4848
};
49+
#pragma pack(pop)
4950

5051
// Visual Studio ignores the 'packed'
5152
STATIC_ASSERT(sizeof(union some_union4)==sizeof(int));
53+
STATIC_ASSERT(__alignof(union some_union4) == 1);
5254

5355
#else
5456

@@ -59,34 +61,38 @@ union some_union4
5961
} __attribute__((__packed__));
6062

6163
STATIC_ASSERT(sizeof(union some_union4)==3);
64+
STATIC_ASSERT(_Alignof(union some_union4) == 1);
6265

6366
#endif
6467

65-
#ifdef _MSC_VER
66-
6768
union some_union5
6869
{
6970
int i;
7071
};
7172

72-
STATIC_ASSERT(__alignof(union some_union5)==1);
73-
73+
#ifdef _MSC_VER
74+
STATIC_ASSERT(__alignof(union some_union5) == 4);
7475
#else
76+
STATIC_ASSERT(_Alignof(union some_union5) == 4);
77+
#endif
7578

76-
union some_union5
77-
{
79+
#ifdef _MSC_VER
80+
#pragma pack(push, 1)
81+
union some_union6 {
7882
int i;
7983
};
84+
#pragma pack(pop)
8085

86+
// Packing may affect alignment
87+
STATIC_ASSERT(__alignof(union some_union6) == 1);
88+
#else
8189
union some_union6
8290
{
8391
int i;
8492
} __attribute__((__packed__));
8593

8694
// Packing may affect alignment
87-
STATIC_ASSERT(_Alignof(union some_union5)==4);
8895
STATIC_ASSERT(_Alignof(union some_union6)==1);
89-
9096
#endif
9197

9298
int main()

0 commit comments

Comments
 (0)