Skip to content

Commit 5c4b091

Browse files
committed
Add wellformedness checks to bitvector types in std_types
1 parent 82465cf commit 5c4b091

File tree

1 file changed

+86
-18
lines changed

1 file changed

+86
-18
lines changed

src/util/std_types.h

Lines changed: 86 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,6 +1196,13 @@ inline bool can_cast_type<bv_typet>(const typet &type)
11961196
return type.id() == ID_bv;
11971197
}
11981198

1199+
inline void validate_type(const bv_typet &type)
1200+
{
1201+
DATA_INVARIANT(!type.get(ID_width).empty(), "bitvector type must have width");
1202+
DATA_INVARIANT(
1203+
type.get_width() > 0, "bitvector type must have non-zero width");
1204+
}
1205+
11991206
/// \brief Cast a typet to a \ref bv_typet
12001207
///
12011208
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1207,14 +1214,18 @@ inline bool can_cast_type<bv_typet>(const typet &type)
12071214
inline const bv_typet &to_bv_type(const typet &type)
12081215
{
12091216
PRECONDITION(can_cast_type<bv_typet>(type));
1210-
return static_cast<const bv_typet &>(type);
1217+
const bv_typet &ret = static_cast<const bv_typet &>(type);
1218+
validate_type(ret);
1219+
return ret;
12111220
}
12121221

12131222
/// \copydoc to_bv_type(const typet &)
12141223
inline bv_typet &to_bv_type(typet &type)
12151224
{
12161225
PRECONDITION(can_cast_type<bv_typet>(type));
1217-
return static_cast<bv_typet &>(type);
1226+
bv_typet &ret = static_cast<bv_typet &>(type);
1227+
validate_type(ret);
1228+
return ret;
12181229
}
12191230

12201231
/// Fixed-width bit-vector with unsigned binary interpretation
@@ -1242,6 +1253,14 @@ inline bool can_cast_type<unsignedbv_typet>(const typet &type)
12421253
return type.id() == ID_unsignedbv;
12431254
}
12441255

1256+
inline void validate_type(const unsignedbv_typet &type)
1257+
{
1258+
DATA_INVARIANT(
1259+
!type.get(ID_width).empty(), "unsigned bitvector type must have width");
1260+
DATA_INVARIANT(
1261+
type.get_width() > 0, "unsigned bitvector type must have non-zero width");
1262+
}
1263+
12451264
/// \brief Cast a typet to an \ref unsignedbv_typet
12461265
///
12471266
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1253,14 +1272,18 @@ inline bool can_cast_type<unsignedbv_typet>(const typet &type)
12531272
inline const unsignedbv_typet &to_unsignedbv_type(const typet &type)
12541273
{
12551274
PRECONDITION(can_cast_type<unsignedbv_typet>(type));
1256-
return static_cast<const unsignedbv_typet &>(type);
1275+
const unsignedbv_typet &ret = static_cast<const unsignedbv_typet &>(type);
1276+
validate_type(ret);
1277+
return ret;
12571278
}
12581279

12591280
/// \copydoc to_unsignedbv_type(const typet &)
12601281
inline unsignedbv_typet &to_unsignedbv_type(typet &type)
12611282
{
12621283
PRECONDITION(can_cast_type<unsignedbv_typet>(type));
1263-
return static_cast<unsignedbv_typet &>(type);
1284+
unsignedbv_typet &ret = static_cast<unsignedbv_typet &>(type);
1285+
validate_type(ret);
1286+
return ret;
12641287
}
12651288

12661289
/// Fixed-width bit-vector with two's complement interpretation
@@ -1288,6 +1311,14 @@ inline bool can_cast_type<signedbv_typet>(const typet &type)
12881311
return type.id() == ID_signedbv;
12891312
}
12901313

1314+
inline void validate_type(const signedbv_typet &type)
1315+
{
1316+
DATA_INVARIANT(
1317+
!type.get(ID_width).empty(), "signed bitvector type must have width");
1318+
DATA_INVARIANT(
1319+
type.get_width() > 0, "signed bitvector type must have non-zero width");
1320+
}
1321+
12911322
/// \brief Cast a typet to a \ref signedbv_typet
12921323
///
12931324
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1299,14 +1330,18 @@ inline bool can_cast_type<signedbv_typet>(const typet &type)
12991330
inline const signedbv_typet &to_signedbv_type(const typet &type)
13001331
{
13011332
PRECONDITION(can_cast_type<signedbv_typet>(type));
1302-
return static_cast<const signedbv_typet &>(type);
1333+
const signedbv_typet &ret = static_cast<const signedbv_typet &>(type);
1334+
validate_type(ret);
1335+
return ret;
13031336
}
13041337

13051338
/// \copydoc to_signedbv_type(const typet &)
13061339
inline signedbv_typet &to_signedbv_type(typet &type)
13071340
{
13081341
PRECONDITION(can_cast_type<signedbv_typet>(type));
1309-
return static_cast<signedbv_typet &>(type);
1342+
signedbv_typet &ret = static_cast<signedbv_typet &>(type);
1343+
validate_type(ret);
1344+
return ret;
13101345
}
13111346

13121347
/// Fixed-width bit-vector with signed fixed-point interpretation
@@ -1342,6 +1377,14 @@ inline bool can_cast_type<fixedbv_typet>(const typet &type)
13421377
return type.id() == ID_fixedbv;
13431378
}
13441379

1380+
inline void validate_type(const fixedbv_typet &type)
1381+
{
1382+
DATA_INVARIANT(
1383+
!type.get(ID_width).empty(), "fixed bitvector type must have width");
1384+
DATA_INVARIANT(
1385+
type.get_width() > 0, "fixed bitvector type must have non-zero width");
1386+
}
1387+
13451388
/// \brief Cast a typet to a \ref fixedbv_typet
13461389
///
13471390
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1353,14 +1396,18 @@ inline bool can_cast_type<fixedbv_typet>(const typet &type)
13531396
inline const fixedbv_typet &to_fixedbv_type(const typet &type)
13541397
{
13551398
PRECONDITION(can_cast_type<fixedbv_typet>(type));
1356-
return static_cast<const fixedbv_typet &>(type);
1399+
const fixedbv_typet &ret = static_cast<const fixedbv_typet &>(type);
1400+
validate_type(ret);
1401+
return ret;
13571402
}
13581403

13591404
/// \copydoc to_fixedbv_type(const typet &)
13601405
inline fixedbv_typet &to_fixedbv_type(typet &type)
13611406
{
13621407
PRECONDITION(can_cast_type<fixedbv_typet>(type));
1363-
return static_cast<fixedbv_typet &>(type);
1408+
fixedbv_typet &ret = static_cast<fixedbv_typet &>(type);
1409+
validate_type(ret);
1410+
return ret;
13641411
}
13651412

13661413
/// Fixed-width bit-vector with IEEE floating-point interpretation
@@ -1394,6 +1441,14 @@ inline bool can_cast_type<floatbv_typet>(const typet &type)
13941441
return type.id() == ID_floatbv;
13951442
}
13961443

1444+
inline void validate_type(const floatbv_typet &type)
1445+
{
1446+
DATA_INVARIANT(
1447+
!type.get(ID_width).empty(), "float bitvector type must have width");
1448+
DATA_INVARIANT(
1449+
type.get_width() > 0, "float bitvector type must have non-zero width");
1450+
}
1451+
13971452
/// \brief Cast a typet to a \ref floatbv_typet
13981453
///
13991454
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1405,14 +1460,18 @@ inline bool can_cast_type<floatbv_typet>(const typet &type)
14051460
inline const floatbv_typet &to_floatbv_type(const typet &type)
14061461
{
14071462
PRECONDITION(can_cast_type<floatbv_typet>(type));
1408-
return static_cast<const floatbv_typet &>(type);
1463+
const floatbv_typet &ret = static_cast<const floatbv_typet &>(type);
1464+
validate_type(ret);
1465+
return ret;
14091466
}
14101467

14111468
/// \copydoc to_floatbv_type(const typet &)
14121469
inline floatbv_typet &to_floatbv_type(typet &type)
14131470
{
14141471
PRECONDITION(can_cast_type<floatbv_typet>(type));
1415-
return static_cast<floatbv_typet &>(type);
1472+
floatbv_typet &ret = static_cast<floatbv_typet &>(type);
1473+
validate_type(ret);
1474+
return ret;
14161475
}
14171476

14181477
/// Type for C bit fields
@@ -1481,6 +1540,11 @@ inline bool can_cast_type<pointer_typet>(const typet &type)
14811540
return type.id() == ID_pointer;
14821541
}
14831542

1543+
inline void validate_type(const pointer_typet &type)
1544+
{
1545+
DATA_INVARIANT(!type.get(ID_width).empty(), "pointer must have width");
1546+
}
1547+
14841548
/// \brief Cast a typet to a \ref pointer_typet
14851549
///
14861550
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1506,12 +1570,6 @@ inline pointer_typet &to_pointer_type(typet &type)
15061570
return ret;
15071571
}
15081572

1509-
inline void validate_type(const pointer_typet &type)
1510-
{
1511-
DATA_INVARIANT(!type.get(ID_width).empty(), "pointer must have width");
1512-
DATA_INVARIANT(type.get_width() > 0, "pointer must have non-zero width");
1513-
}
1514-
15151573
/// The reference type
15161574
///
15171575
/// Intends to model C++ reference. Comparing to \ref pointer_typet should
@@ -1584,6 +1642,12 @@ inline bool can_cast_type<c_bool_typet>(const typet &type)
15841642
return type.id() == ID_c_bool;
15851643
}
15861644

1645+
inline void validate_type(const c_bool_typet &type)
1646+
{
1647+
DATA_INVARIANT(!type.get(ID_width).empty(), "C bool type must have width");
1648+
DATA_INVARIANT(type.get_width() > 0, "C bool type must have non-zero width");
1649+
}
1650+
15871651
/// \brief Cast a typet to a \ref c_bool_typet
15881652
///
15891653
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1595,14 +1659,18 @@ inline bool can_cast_type<c_bool_typet>(const typet &type)
15951659
inline const c_bool_typet &to_c_bool_type(const typet &type)
15961660
{
15971661
PRECONDITION(can_cast_type<c_bool_typet>(type));
1598-
return static_cast<const c_bool_typet &>(type);
1662+
const c_bool_typet &ret = static_cast<const c_bool_typet &>(type);
1663+
validate_type(ret);
1664+
return ret;
15991665
}
16001666

16011667
/// \copydoc to_c_bool_type(const typet &)
16021668
inline c_bool_typet &to_c_bool_type(typet &type)
16031669
{
16041670
PRECONDITION(can_cast_type<c_bool_typet>(type));
1605-
return static_cast<c_bool_typet &>(type);
1671+
c_bool_typet &ret = static_cast<c_bool_typet &>(type);
1672+
validate_type(ret);
1673+
return ret;
16061674
}
16071675

16081676
/// String type

0 commit comments

Comments
 (0)