Skip to content

Commit 5e0a2fe

Browse files
committed
Add wellformedness checks to bitvector types in std_types
1 parent a6d710f commit 5e0a2fe

File tree

1 file changed

+141
-8
lines changed

1 file changed

+141
-8
lines changed

src/util/std_types.h

Lines changed: 141 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,14 +1149,34 @@ class bv_typet:public bitvector_typet
11491149
inline const bv_typet &to_bv_type(const typet &type)
11501150
{
11511151
PRECONDITION(type.id()==ID_bv);
1152-
return static_cast<const bv_typet &>(type);
1152+
const bv_typet &ret = static_cast<const bv_typet &>(type);
1153+
validate_type(ret);
1154+
return ret;
11531155
}
11541156

11551157
/// \copydoc to_bv_type(const typet &)
11561158
inline bv_typet &to_bv_type(typet &type)
11571159
{
11581160
PRECONDITION(type.id()==ID_bv);
1159-
return static_cast<bv_typet &>(type);
1161+
bv_typet &ret = static_cast<bv_typet &>(type);
1162+
validate_type(ret);
1163+
return ret;
1164+
}
1165+
1166+
/// Check whether a reference to a typet is a \ref bv_typet.
1167+
/// \param type Source type.
1168+
/// \return True if \param type is a \ref bv_typet.
1169+
template <>
1170+
inline bool can_cast_type<bv_typet>(const typet &type)
1171+
{
1172+
return type.id() == ID_bv;
1173+
}
1174+
1175+
inline void validate_type(const bv_typet &type)
1176+
{
1177+
DATA_INVARIANT(!type.get(ID_width).empty(), "bitvector type must have width");
1178+
DATA_INVARIANT(
1179+
type.get_width() > 0, "bitvector type must have non-zero width");
11601180
}
11611181

11621182
/// Fixed-width bit-vector with unsigned binary interpretation
@@ -1186,14 +1206,35 @@ class unsignedbv_typet:public bitvector_typet
11861206
inline const unsignedbv_typet &to_unsignedbv_type(const typet &type)
11871207
{
11881208
PRECONDITION(type.id()==ID_unsignedbv);
1189-
return static_cast<const unsignedbv_typet &>(type);
1209+
const unsignedbv_typet &ret = static_cast<const unsignedbv_typet &>(type);
1210+
validate_type(ret);
1211+
return ret;
11901212
}
11911213

11921214
/// \copydoc to_unsignedbv_type(const typet &)
11931215
inline unsignedbv_typet &to_unsignedbv_type(typet &type)
11941216
{
11951217
PRECONDITION(type.id()==ID_unsignedbv);
1196-
return static_cast<unsignedbv_typet &>(type);
1218+
unsignedbv_typet &ret = static_cast<unsignedbv_typet &>(type);
1219+
validate_type(ret);
1220+
return ret;
1221+
}
1222+
1223+
/// Check whether a reference to a typet is a \ref unsignedbv_typet.
1224+
/// \param type Source type.
1225+
/// \return True if \param type is a \ref unsignedbv_typet.
1226+
template <>
1227+
inline bool can_cast_type<unsignedbv_typet>(const typet &type)
1228+
{
1229+
return type.id() == ID_unsignedbv;
1230+
}
1231+
1232+
inline void validate_type(const unsignedbv_typet &type)
1233+
{
1234+
DATA_INVARIANT(
1235+
!type.get(ID_width).empty(), "unsigned bitvector type must have width");
1236+
DATA_INVARIANT(
1237+
type.get_width() > 0, "unsigned bitvector type must have non-zero width");
11971238
}
11981239

11991240
/// Fixed-width bit-vector with two's complement interpretation
@@ -1223,14 +1264,35 @@ class signedbv_typet:public bitvector_typet
12231264
inline const signedbv_typet &to_signedbv_type(const typet &type)
12241265
{
12251266
PRECONDITION(type.id()==ID_signedbv);
1226-
return static_cast<const signedbv_typet &>(type);
1267+
const signedbv_typet &ret = static_cast<const signedbv_typet &>(type);
1268+
validate_type(ret);
1269+
return ret;
12271270
}
12281271

12291272
/// \copydoc to_signedbv_type(const typet &)
12301273
inline signedbv_typet &to_signedbv_type(typet &type)
12311274
{
12321275
PRECONDITION(type.id()==ID_signedbv);
1233-
return static_cast<signedbv_typet &>(type);
1276+
signedbv_typet &ret = static_cast<signedbv_typet &>(type);
1277+
validate_type(ret);
1278+
return ret;
1279+
}
1280+
1281+
/// Check whether a reference to a typet is a \ref signedbv_typet.
1282+
/// \param type Source type.
1283+
/// \return True if \param type is a \ref signedbv_typet.
1284+
template <>
1285+
inline bool can_cast_type<signedbv_typet>(const typet &type)
1286+
{
1287+
return type.id() == ID_signedbv;
1288+
}
1289+
1290+
inline void validate_type(const signedbv_typet &type)
1291+
{
1292+
DATA_INVARIANT(
1293+
!type.get(ID_width).empty(), "signed bitvector type must have width");
1294+
DATA_INVARIANT(
1295+
type.get_width() > 0, "signed bitvector type must have non-zero width");
12341296
}
12351297

12361298
/// Fixed-width bit-vector with signed fixed-point interpretation
@@ -1268,7 +1330,35 @@ class fixedbv_typet:public bitvector_typet
12681330
inline const fixedbv_typet &to_fixedbv_type(const typet &type)
12691331
{
12701332
PRECONDITION(type.id()==ID_fixedbv);
1271-
return static_cast<const fixedbv_typet &>(type);
1333+
const fixedbv_typet &ret = static_cast<const fixedbv_typet &>(type);
1334+
validate_type(ret);
1335+
return ret;
1336+
}
1337+
1338+
/// \copydoc to_fixedbv_type(const typet &)
1339+
inline fixedbv_typet &to_fixedbv_type(typet &type)
1340+
{
1341+
PRECONDITION(type.id() == ID_fixedbv);
1342+
fixedbv_typet &ret = static_cast<fixedbv_typet &>(type);
1343+
validate_type(ret);
1344+
return ret;
1345+
}
1346+
1347+
/// Check whether a reference to a typet is a \ref fixedbv_typet.
1348+
/// \param type Source type.
1349+
/// \return True if \param type is a \ref fixedbv_typet.
1350+
template <>
1351+
inline bool can_cast_type<fixedbv_typet>(const typet &type)
1352+
{
1353+
return type.id() == ID_fixedbv;
1354+
}
1355+
1356+
inline void validate_type(const fixedbv_typet &type)
1357+
{
1358+
DATA_INVARIANT(
1359+
!type.get(ID_width).empty(), "fixed bitvector type must have width");
1360+
DATA_INVARIANT(
1361+
type.get_width() > 0, "fixed bitvector type must have non-zero width");
12721362
}
12731363

12741364
/// Fixed-width bit-vector with IEEE floating-point interpretation
@@ -1304,7 +1394,35 @@ class floatbv_typet:public bitvector_typet
13041394
inline const floatbv_typet &to_floatbv_type(const typet &type)
13051395
{
13061396
PRECONDITION(type.id()==ID_floatbv);
1307-
return static_cast<const floatbv_typet &>(type);
1397+
const floatbv_typet &ret = static_cast<const floatbv_typet &>(type);
1398+
validate_type(ret);
1399+
return ret;
1400+
}
1401+
1402+
/// \copydoc to_floatbv_type(const typet &)
1403+
inline floatbv_typet &to_floatbv_type(typet &type)
1404+
{
1405+
PRECONDITION(type.id() == ID_floatbv);
1406+
floatbv_typet &ret = static_cast<floatbv_typet &>(type);
1407+
validate_type(ret);
1408+
return ret;
1409+
}
1410+
1411+
/// Check whether a reference to a typet is a \ref floatbv_typet.
1412+
/// \param type Source type.
1413+
/// \return True if \param type is a \ref floatbv_typet.
1414+
template <>
1415+
inline bool can_cast_type<floatbv_typet>(const typet &type)
1416+
{
1417+
return type.id() == ID_floatbv;
1418+
}
1419+
1420+
inline void validate_type(const floatbv_typet &type)
1421+
{
1422+
DATA_INVARIANT(
1423+
!type.get(ID_width).empty(), "float bitvector type must have width");
1424+
DATA_INVARIANT(
1425+
type.get_width() > 0, "float bitvector type must have non-zero width");
13081426
}
13091427

13101428
/// Type for C bit fields
@@ -1471,6 +1589,21 @@ inline c_bool_typet &to_c_bool_type(typet &type)
14711589
return static_cast<c_bool_typet &>(type);
14721590
}
14731591

1592+
/// Check whether a reference to a typet is a \ref c_bool_typet.
1593+
/// \param type Source type.
1594+
/// \return True if \param type is a \ref c_bool_typet.
1595+
template <>
1596+
inline bool can_cast_type<c_bool_typet>(const typet &type)
1597+
{
1598+
return type.id() == ID_c_bool;
1599+
}
1600+
1601+
inline void validate_type(const c_bool_typet &type)
1602+
{
1603+
DATA_INVARIANT(!type.get(ID_width).empty(), "C bool type must have width");
1604+
DATA_INVARIANT(type.get_width() > 0, "C bool type must have non-zero width");
1605+
}
1606+
14741607
/// String type
14751608
///
14761609
/// Represents string constants, such as `@class_identifier`.

0 commit comments

Comments
 (0)