Skip to content

Commit 8845b6c

Browse files
committed
Make signed/unsigned bitfields the same as gcc/clang
1 parent 199e135 commit 8845b6c

File tree

3 files changed

+151
-73
lines changed

3 files changed

+151
-73
lines changed

tccgen.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2959,15 +2959,17 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op)
29592959
if (bt2 == VT_LLONG)
29602960
type.t &= t2;
29612961
/* convert to unsigned if it does not fit in a long long */
2962-
if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
2963-
(t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
2962+
if ((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED) ||
2963+
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
29642964
type.t |= VT_UNSIGNED;
29652965
} else {
2966+
int t1_bit = BIT_SIZE(t1) <= 31 ? VT_BITFIELD : 0;
2967+
int t2_bit = BIT_SIZE(t2) <= 31 ? VT_BITFIELD : 0;
29662968
/* integer operations */
29672969
type.t = VT_INT | (VT_LONG & (t1 | t2));
29682970
/* convert to unsigned if it does not fit in an integer */
2969-
if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
2970-
(t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
2971+
if ((t1 & (VT_BTYPE | VT_UNSIGNED | t1_bit)) == (VT_INT | VT_UNSIGNED) ||
2972+
(t2 & (VT_BTYPE | VT_UNSIGNED | t2_bit)) == (VT_INT | VT_UNSIGNED))
29712973
type.t |= VT_UNSIGNED;
29722974
}
29732975
if (dest)
@@ -4554,6 +4556,7 @@ static void struct_decl(CType *type, int u)
45544556
tcc_error("width of '%s' exceeds its type",
45554557
get_tok_str(v, NULL));
45564558
} else if (bit_size == bsize
4559+
&& !*tcc_state->pack_stack_ptr
45574560
&& !ad.a.packed && !ad1.a.packed) {
45584561
/* no need for bit fields */
45594562
;

tests/tests2/93_integer_promotion.c

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,66 +6,106 @@ int printf(const char*, ...);
66
int main (void)
77
{
88
struct {
9-
unsigned ub:3;
10-
unsigned u:32;
11-
unsigned long long ullb:35;
12-
unsigned long long ull:64;
9+
unsigned u3:3;
10+
unsigned u31:31;
11+
unsigned u32:32;
12+
unsigned long ul31:31;
13+
unsigned long ul32:32;
14+
unsigned long long ull31:31;
15+
unsigned long long ull32:32;
16+
unsigned long long ull33:33;
17+
unsigned long long ull64:64;
1318
unsigned char c;
14-
} s = { 1, 1, 1 };
19+
} s = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1520

16-
promote(s.ub);
17-
promote(s.u);
18-
promote(s.ullb);
19-
promote(s.ull);
21+
promote(s.u3);
22+
promote(s.u31);
23+
promote(s.u32);
24+
promote(s.ul31);
25+
promote(s.ul32);
26+
promote(s.ull31);
27+
promote(s.ull32);
28+
promote(s.ull33);
29+
promote(s.ull64);
2030
promote(s.c);
2131
printf("\n");
2232

23-
promote((1 ? s.ub : 1));
24-
promote((1 ? s.u : 1));
25-
promote((1 ? s.ullb : 1));
26-
promote((1 ? s.ull : 1));
33+
promote((1 ? s.u3 : 1));
34+
promote((1 ? s.u31 : 1));
35+
promote((1 ? s.u32 : 1));
36+
promote((1 ? s.ul31 : 1));
37+
promote((1 ? s.ul32 : 1));
38+
promote((1 ? s.ull31 : 1));
39+
promote((1 ? s.ull32 : 1));
40+
promote((1 ? s.ull33 : 1));
41+
promote((1 ? s.ull64 : 1));
2742
promote((1 ? s.c : 1));
2843
printf("\n");
2944

30-
promote(s.ub << 1);
31-
promote(s.u << 1);
32-
promote(s.ullb << 1);
33-
promote(s.ull << 1);
45+
promote(s.u3 << 1);
46+
promote(s.u31 << 1);
47+
promote(s.u32 << 1);
48+
promote(s.ul31 << 1);
49+
promote(s.ul32 << 1);
50+
promote(s.ull31 << 1);
51+
promote(s.ull32 << 1);
52+
promote(s.ull33 << 1);
53+
promote(s.ull64 << 1);
3454
promote(s.c << 1);
3555
printf("\n");
3656

37-
promote(+s.ub);
38-
promote(+s.u);
39-
promote(+s.ullb);
40-
promote(+s.ull);
57+
promote(+s.u3);
58+
promote(+s.u31);
59+
promote(+s.u32);
60+
promote(+s.ul31);
61+
promote(+s.ul32);
62+
promote(+s.ull31);
63+
promote(+s.ull32);
64+
promote(+s.ull33);
65+
promote(+s.ull64);
4166
promote(+s.c);
4267
printf("\n");
4368

44-
promote(-s.ub);
45-
promote(-s.u);
46-
promote(-s.ullb);
47-
promote(-s.ull);
69+
promote(-s.u3);
70+
promote(-s.u31);
71+
promote(-s.u32);
72+
promote(-s.ul31);
73+
promote(-s.ul32);
74+
promote(-s.ull31);
75+
promote(-s.ull32);
76+
promote(-s.ull33);
77+
promote(-s.ull64);
4878
promote(-s.c);
4979
printf("\n");
5080

51-
promote(~s.ub);
52-
promote(~s.u);
53-
promote(~s.ullb);
54-
promote(~s.ull);
81+
promote(~s.u3);
82+
promote(~s.u31);
83+
promote(~s.u32);
84+
promote(~s.ul31);
85+
promote(~s.ul32);
86+
promote(~s.ull31);
87+
promote(~s.ull32);
88+
promote(~s.ull33);
89+
promote(~s.ull64);
5590
promote(~s.c);
5691
printf("\n");
5792

58-
promote(!s.ub);
59-
promote(!s.u);
60-
promote(!s.ullb);
61-
promote(!s.ull);
93+
promote(!s.u3);
94+
promote(!s.u31);
95+
promote(!s.u32);
96+
promote(!s.ul31);
97+
promote(!s.ul32);
98+
promote(!s.ull31);
99+
promote(!s.ull32);
100+
promote(!s.ull33);
101+
promote(!s.ull64);
62102
promote(!s.c);
63103
printf("\n");
64104

65-
promote(+(unsigned)s.ub);
66-
promote(-(unsigned)s.ub);
67-
promote(~(unsigned)s.ub);
68-
promote(!(unsigned)s.ub);
105+
promote(+(unsigned)s.u3);
106+
promote(-(unsigned)s.u3);
107+
promote(~(unsigned)s.u3);
108+
promote(!(unsigned)s.u3);
69109

70110
return 0;
71111
}
Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,81 @@
1-
signed : s.ub
2-
unsigned : s.u
3-
signed : s.ullb
4-
unsigned : s.ull
1+
signed : s.u3
2+
signed : s.u31
3+
unsigned : s.u32
4+
signed : s.ul31
5+
unsigned : s.ul32
6+
signed : s.ull31
7+
unsigned : s.ull32
8+
unsigned : s.ull33
9+
unsigned : s.ull64
510
signed : s.c
611

7-
signed : (1 ? s.ub : 1)
8-
unsigned : (1 ? s.u : 1)
9-
signed : (1 ? s.ullb : 1)
10-
unsigned : (1 ? s.ull : 1)
12+
signed : (1 ? s.u3 : 1)
13+
signed : (1 ? s.u31 : 1)
14+
unsigned : (1 ? s.u32 : 1)
15+
signed : (1 ? s.ul31 : 1)
16+
unsigned : (1 ? s.ul32 : 1)
17+
signed : (1 ? s.ull31 : 1)
18+
unsigned : (1 ? s.ull32 : 1)
19+
unsigned : (1 ? s.ull33 : 1)
20+
unsigned : (1 ? s.ull64 : 1)
1121
signed : (1 ? s.c : 1)
1222

13-
signed : s.ub << 1
14-
unsigned : s.u << 1
15-
signed : s.ullb << 1
16-
unsigned : s.ull << 1
23+
signed : s.u3 << 1
24+
signed : s.u31 << 1
25+
unsigned : s.u32 << 1
26+
signed : s.ul31 << 1
27+
unsigned : s.ul32 << 1
28+
signed : s.ull31 << 1
29+
unsigned : s.ull32 << 1
30+
unsigned : s.ull33 << 1
31+
unsigned : s.ull64 << 1
1732
signed : s.c << 1
1833

19-
signed : +s.ub
20-
unsigned : +s.u
21-
signed : +s.ullb
22-
unsigned : +s.ull
34+
signed : +s.u3
35+
signed : +s.u31
36+
unsigned : +s.u32
37+
signed : +s.ul31
38+
unsigned : +s.ul32
39+
signed : +s.ull31
40+
unsigned : +s.ull32
41+
unsigned : +s.ull33
42+
unsigned : +s.ull64
2343
signed : +s.c
2444

25-
signed : -s.ub
26-
unsigned : -s.u
27-
signed : -s.ullb
28-
unsigned : -s.ull
45+
signed : -s.u3
46+
signed : -s.u31
47+
unsigned : -s.u32
48+
signed : -s.ul31
49+
unsigned : -s.ul32
50+
signed : -s.ull31
51+
unsigned : -s.ull32
52+
unsigned : -s.ull33
53+
unsigned : -s.ull64
2954
signed : -s.c
3055

31-
signed : ~s.ub
32-
unsigned : ~s.u
33-
signed : ~s.ullb
34-
unsigned : ~s.ull
56+
signed : ~s.u3
57+
signed : ~s.u31
58+
unsigned : ~s.u32
59+
signed : ~s.ul31
60+
unsigned : ~s.ul32
61+
signed : ~s.ull31
62+
unsigned : ~s.ull32
63+
unsigned : ~s.ull33
64+
unsigned : ~s.ull64
3565
signed : ~s.c
3666

37-
signed : !s.ub
38-
signed : !s.u
39-
signed : !s.ullb
40-
signed : !s.ull
67+
signed : !s.u3
68+
signed : !s.u31
69+
signed : !s.u32
70+
signed : !s.ul31
71+
signed : !s.ul32
72+
signed : !s.ull31
73+
signed : !s.ull32
74+
signed : !s.ull33
75+
signed : !s.ull64
4176
signed : !s.c
4277

43-
unsigned : +(unsigned)s.ub
44-
unsigned : -(unsigned)s.ub
45-
unsigned : ~(unsigned)s.ub
46-
signed : !(unsigned)s.ub
78+
unsigned : +(unsigned)s.u3
79+
unsigned : -(unsigned)s.u3
80+
unsigned : ~(unsigned)s.u3
81+
signed : !(unsigned)s.u3

0 commit comments

Comments
 (0)