@@ -1019,7 +1019,7 @@ void c_typecheck_baset::typecheck_compound_body(
10191019
10201020/* ******************************************************************\
10211021
1022- Function: c_typecheck_baset::fitting_int_type
1022+ Function: c_typecheck_baset::enum_constant_type
10231023
10241024 Inputs:
10251025
@@ -1029,34 +1029,92 @@ Function: c_typecheck_baset::fitting_int_type
10291029
10301030\*******************************************************************/
10311031
1032- typet c_typecheck_baset::fitting_int_type (
1032+ typet c_typecheck_baset::enum_constant_type (
10331033 const mp_integer &min_value,
1034- const mp_integer &max_value,
1035- bool at_least_int) const
1034+ const mp_integer &max_value) const
10361035{
1037- if (max_value<(mp_integer (1 )<<(config.ansi_c .char_width -1 )) &&
1038- min_value>=-(mp_integer (1 )<<(config.ansi_c .char_width -1 )))
1039- return at_least_int?signed_int_type ():signed_char_type ();
1040- else if (max_value<(mp_integer (1 )<<config.ansi_c .char_width ) &&
1041- min_value>=0 )
1042- return at_least_int?signed_int_type ():unsigned_char_type ();
1043- else if (max_value<(mp_integer (1 )<<(config.ansi_c .short_int_width -1 )) &&
1044- min_value>=-(mp_integer (1 )<<(config.ansi_c .short_int_width -1 )))
1045- return at_least_int?signed_int_type ():signed_short_int_type ();
1046- else if (max_value<(mp_integer (1 )<<config.ansi_c .short_int_width ) &&
1047- min_value>=0 )
1048- return at_least_int?signed_int_type ():unsigned_short_int_type ();
1049- else if (max_value<(mp_integer (1 )<<(config.ansi_c .int_width -1 )) &&
1050- min_value>=-(mp_integer (1 )<<(config.ansi_c .int_width -1 )))
1036+ // enum constants are at least 'int', but may be made larger.
1037+ // 'Packing' has no influence.
1038+ if (max_value<(mp_integer (1 )<<(config.ansi_c .int_width -1 )) &&
1039+ min_value>=-(mp_integer (1 )<<(config.ansi_c .int_width -1 )))
10511040 return signed_int_type ();
10521041 else if (max_value<(mp_integer (1 )<<config.ansi_c .int_width ) &&
10531042 min_value>=0 )
10541043 return unsigned_int_type ();
1055- else if (max_value<(mp_integer (1 )<<(config.ansi_c .long_long_int_width -1 )) &&
1056- min_value>=-(mp_integer (1 )<<(config.ansi_c .long_long_int_width -1 )))
1044+ else if (max_value<(mp_integer (1 )<<config.ansi_c .long_int_width ) &&
1045+ min_value>=0 )
1046+ return unsigned_long_int_type ();
1047+ else if (max_value<(mp_integer (1 )<<config.ansi_c .long_long_int_width ) &&
1048+ min_value>=0 )
1049+ return unsigned_long_long_int_type ();
1050+ else if (max_value<(mp_integer (1 )<<(config.ansi_c .long_int_width -1 )) &&
1051+ min_value>=-(mp_integer (1 )<<(config.ansi_c .long_int_width -1 )))
1052+ return signed_long_int_type ();
1053+ else
10571054 return signed_long_long_int_type ();
1055+ }
1056+
1057+ /* ******************************************************************\
1058+
1059+ Function: c_typecheck_baset::enum_underlying_type
1060+
1061+ Inputs:
1062+
1063+ Outputs:
1064+
1065+ Purpose:
1066+
1067+ \*******************************************************************/
1068+
1069+ typet c_typecheck_baset::enum_underlying_type (
1070+ const mp_integer &min_value,
1071+ const mp_integer &max_value,
1072+ bool is_packed) const
1073+ {
1074+ if (min_value<0 )
1075+ {
1076+ // We'll want a signed type.
1077+
1078+ if (is_packed)
1079+ {
1080+ // If packed, there are smaller options.
1081+ if (max_value<(mp_integer (1 )<<(config.ansi_c .char_width -1 )) &&
1082+ min_value>=-(mp_integer (1 )<<(config.ansi_c .char_width -1 )))
1083+ return signed_char_type ();
1084+ else if (max_value<(mp_integer (1 )<<(config.ansi_c .short_int_width -1 )) &&
1085+ min_value>=-(mp_integer (1 )<<(config.ansi_c .short_int_width -1 )))
1086+ return signed_short_int_type ();
1087+ }
1088+
1089+ if (max_value<(mp_integer (1 )<<(config.ansi_c .int_width -1 )) &&
1090+ min_value>=-(mp_integer (1 )<<(config.ansi_c .int_width -1 )))
1091+ return signed_int_type ();
1092+ else if (max_value<(mp_integer (1 )<<(config.ansi_c .long_int_width -1 )) &&
1093+ min_value>=-(mp_integer (1 )<<(config.ansi_c .long_int_width -1 )))
1094+ return signed_long_int_type ();
1095+ else
1096+ return signed_long_long_int_type ();
1097+ }
10581098 else
1059- return unsigned_long_long_int_type ();
1099+ {
1100+ // We'll want an unsigned type.
1101+
1102+ if (is_packed)
1103+ {
1104+ // If packed, there are smaller options.
1105+ if (max_value<(mp_integer (1 )<<config.ansi_c .char_width ))
1106+ return unsigned_char_type ();
1107+ else if (max_value<(mp_integer (1 )<<config.ansi_c .short_int_width ))
1108+ return unsigned_short_int_type ();
1109+ }
1110+
1111+ if (max_value<(mp_integer (1 )<<config.ansi_c .int_width ))
1112+ return unsigned_int_type ();
1113+ else if (max_value<(mp_integer (1 )<<config.ansi_c .long_int_width ))
1114+ return unsigned_long_int_type ();
1115+ else
1116+ return unsigned_long_long_int_type ();
1117+ }
10601118}
10611119
10621120/* ******************************************************************\
@@ -1129,13 +1187,12 @@ void c_typecheck_baset::typecheck_c_enum_type(typet &type)
11291187 if (value<min_value) min_value=value;
11301188 if (value>max_value) max_value=value;
11311189
1132- // The type of the enum constant is 'int', unless it it's larger.
1133- typet underlying_type=
1134- fitting_int_type (min_value, max_value, true );
1190+ typet constant_type=
1191+ enum_constant_type (min_value, max_value);
11351192
1136- v=from_integer (value, underlying_type );
1193+ v=from_integer (value, constant_type );
11371194
1138- declaration.type ()=underlying_type ;
1195+ declaration.type ()=constant_type ;
11391196 typecheck_declaration (declaration);
11401197
11411198 irep_idt base_name=
@@ -1208,14 +1265,9 @@ void c_typecheck_baset::typecheck_c_enum_type(typet &type)
12081265 body.push_back (*it);
12091266
12101267 // We use a subtype to store the underlying type.
1211- // This is at least 'int' unless packed if negative,
1212- // and at least 'unsigned int' otherwise.
12131268 typet underlying_type=
1214- fitting_int_type (min_value, max_value, !is_packed);
1215- if (underlying_type==signed_int_type () &&
1216- min_value>=0 )
1217- underlying_type=unsigned_int_type ();
1218-
1269+ enum_underlying_type (min_value, max_value, is_packed);
1270+
12191271 enum_tag_symbol.type .subtype ()=underlying_type;
12201272
12211273 // is it in the symbol table already?
0 commit comments