History

Fix unsigned enum bit-fields

See testcase. If an enum has only positive values, fits N bits, and is placed in a N-bit bit-field that bit-fields must be treated as unsigned, not signed.

Michael Matz committed 9 years ago

Commit 07572341 parent a7a36273 files · +60 −1Browse files

Unified · Split

3 files
  1. tccgen.c +3 −1
  2. tests/tests2/92_enum_bitfield.c +57 −0
  3. tests/tests2/92_enum_bitfield.expect +0 −0
tccgen.c+3−1
@@ -1082,7 +1082,9 @@ ST_FUNC int gv(int rc) · 1081 unmodified lines
1082 } else1082 } else
1083 type.t = VT_INT;1083 type.t = VT_INT;
1084 if((vtop->type.t & VT_UNSIGNED) ||1084 if((vtop->type.t & VT_UNSIGNED) ||
1085 (vtop->type.t & VT_BTYPE) == VT_BOOL)1085 (vtop->type.t & VT_BTYPE) == VT_BOOL ||
1086 (((vtop->type.t & VT_BTYPE) == VT_ENUM) &&
1087 vtop->type.ref->a.unsigned_enum))
1086 type.t |= VT_UNSIGNED;1088 type.t |= VT_UNSIGNED;
1087 gen_cast(&type);1089 gen_cast(&type);
1088 /* generate shifts */1090 /* generate shifts */
tests/tests2/92_enum_bitfield.c+57−0
@@ -0,0 +1,57 @@
1/* This checks if enums needing 8 bit but only having positive
2 values are correctly zero extended (instead of sign extended)
3 when stored into/loaded from a 8 bit bit-field of enum type (which
4 itself is implementation defined, so isn't necessarily supported by all
5 other compilers). */
6enum tree_code {
7 SOME_CODE = 148, /* has bit 7 set, and hence all further enum values as well */
8 LAST_AND_UNUSED_TREE_CODE
9};
10typedef union tree_node *tree;
11struct tree_common
12{
13 union tree_node *chain;
14 union tree_node *type;
15 enum tree_code code : 8;
16 unsigned side_effects_flag : 1;
17};
18union tree_node
19{
20 struct tree_common common;
21 };
22enum c_tree_code {
23 C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE,
24 STMT_EXPR,
25 LAST_C_TREE_CODE
26};
27enum cplus_tree_code {
28 CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE,
29 AMBIG_CONV,
30 LAST_CPLUS_TREE_CODE
31};
32
33extern int printf(const char *, ...);
34int blah(){return 0;}
35
36int convert_like_real (tree convs)
37{
38 switch (((enum tree_code) (convs)->common.code))
39 {
40 case AMBIG_CONV: /* This has bit 7 set, which must not be the sign
41 bit in tree_common.code, i.e. the bitfield must
42 be somehow marked unsigned. */
43 return blah();
44 default:
45 break;
46 };
47 printf("unsigned enum bit-fields broken\n");
48}
49
50int main()
51{
52 union tree_node convs;
53
54 convs.common.code = AMBIG_CONV;
55 convert_like_real (&convs);
56 return 0;
57}
tests/tests2/92_enum_bitfield.expect+0−0

Empty file added.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t