Skip to content

Commit 88c4a2e

Browse files
committed
Set enum underlying type from specified type
1 parent 37b95f0 commit 88c4a2e

File tree

1 file changed

+44
-7
lines changed

1 file changed

+44
-7
lines changed

src/ansi-c/c_typecheck_type.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,10 +1160,20 @@ void c_typecheck_baset::typecheck_c_enum_type(typet &type)
11601160
throw 0;
11611161
}
11621162

1163-
if(as_expr.find(ID_enum_underlying_type).is_not_nil())
1163+
const bool have_underlying_type =
1164+
type.find_type(ID_enum_underlying_type).is_not_nil();
1165+
1166+
if(have_underlying_type)
11641167
{
1165-
warning().source_location = source_location;
1166-
warning() << "ignoring specification of underlying type for enum" << eom;
1168+
typecheck_type(type.add_type(ID_enum_underlying_type));
1169+
1170+
if(!is_signed_or_unsigned_bitvector(
1171+
static_cast<const typet &>(type.find(ID_enum_underlying_type))))
1172+
{
1173+
error().source_location = source_location;
1174+
error() << "underlying type for enum must be an integral type" << eom;
1175+
throw 0;
1176+
}
11671177
}
11681178

11691179
// enums start at zero;
@@ -1211,8 +1221,26 @@ void c_typecheck_baset::typecheck_c_enum_type(typet &type)
12111221
if(value>max_value)
12121222
max_value=value;
12131223

1214-
typet constant_type=
1215-
enum_constant_type(min_value, max_value);
1224+
typet constant_type;
1225+
1226+
if(have_underlying_type)
1227+
{
1228+
constant_type = type.find_type(ID_enum_underlying_type);
1229+
const auto &tmp = to_integer_bitvector_type(constant_type);
1230+
1231+
if(value < tmp.smallest() || value > tmp.largest())
1232+
{
1233+
error().source_location = v.source_location();
1234+
error()
1235+
<< "enum constant value cannot be represented with underlying type"
1236+
<< eom;
1237+
throw 0;
1238+
}
1239+
}
1240+
else
1241+
{
1242+
constant_type = enum_constant_type(min_value, max_value);
1243+
}
12161244

12171245
v=from_integer(value, constant_type);
12181246

@@ -1245,8 +1273,17 @@ void c_typecheck_baset::typecheck_c_enum_type(typet &type)
12451273
bool is_packed=type.get_bool(ID_C_packed);
12461274

12471275
// We use a subtype to store the underlying type.
1248-
bitvector_typet underlying_type =
1249-
enum_underlying_type(min_value, max_value, is_packed);
1276+
bitvector_typet underlying_type(ID_nil);
1277+
1278+
if(have_underlying_type)
1279+
{
1280+
underlying_type =
1281+
to_bitvector_type(type.find_type(ID_enum_underlying_type));
1282+
}
1283+
else
1284+
{
1285+
underlying_type = enum_underlying_type(min_value, max_value, is_packed);
1286+
}
12501287

12511288
// Get the width to make the values have a bitvector type
12521289
std::size_t width = underlying_type.get_width();

0 commit comments

Comments
 (0)