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
10821082 } else
10831083 type.t = VT_INT;
10841084 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))
10861088 type.t |= VT_UNSIGNED;
10871089 gen_cast(&type);
10881090 /* 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). */
6+enum 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+};
10+typedef union tree_node *tree;
11+struct 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+};
18+union tree_node
19+{
20+ struct tree_common common;
21+ };
22+enum c_tree_code {
23+ C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE,
24+ STMT_EXPR,
25+ LAST_C_TREE_CODE
26+};
27+enum cplus_tree_code {
28+ CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE,
29+ AMBIG_CONV,
30+ LAST_CPLUS_TREE_CODE
31+};
32+
33+extern int printf(const char *, ...);
34+int blah(){return 0;}
35+
36+int 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+
50+int 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