Skip to content

Commit 35691f5

Browse files
committed
Migrate existing type checks to new framework
This removes the validate_type() methods and moves the checks into a new method check() of the corresponding type.
1 parent 582559f commit 35691f5

File tree

3 files changed

+93
-86
lines changed

3 files changed

+93
-86
lines changed

src/util/expr_cast.h

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,6 @@ inline bool can_cast_type(const typet &base);
4848
/// validate objects in this way at any time.
4949
inline void validate_expr(const exprt &) {}
5050

51-
/// Called after casting. Provides a point to check data invariants on the
52-
/// structure of the typet. By default, this is a no-op, but you can provide an
53-
/// overload to validate particular types. Should always succeed unless the
54-
/// program has entered an invalid state. We validate objects at cast time as
55-
/// that is when these checks have been used historically, but it would be
56-
/// reasonable to validate objects in this way at any time.
57-
inline void validate_type(const typet &)
58-
{
59-
}
60-
6151
namespace detail // NOLINT
6252
{
6353

@@ -129,9 +119,8 @@ auto type_try_dynamic_cast(TType &base) ->
129119
"The template argument T must be derived from typet.");
130120
if(!can_cast_type<typename std::remove_const<T>::type>(base))
131121
return nullptr;
132-
const auto ret = static_cast<returnt>(&base);
133-
validate_type(*ret);
134-
return ret;
122+
TType::check(base);
123+
return static_cast<returnt>(&base);
135124
}
136125

137126
namespace detail // NOLINT

src/util/std_types.h

Lines changed: 69 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,15 +1002,13 @@ inline bool can_cast_type<code_typet>(const typet &type)
10021002
inline const code_typet &to_code_type(const typet &type)
10031003
{
10041004
PRECONDITION(can_cast_type<code_typet>(type));
1005-
validate_type(type);
10061005
return static_cast<const code_typet &>(type);
10071006
}
10081007

10091008
/// \copydoc to_code_type(const typet &)
10101009
inline code_typet &to_code_type(typet &type)
10111010
{
10121011
PRECONDITION(can_cast_type<code_typet>(type));
1013-
validate_type(type);
10141012
return static_cast<code_typet &>(type);
10151013
}
10161014

@@ -1190,6 +1188,13 @@ class bv_typet:public bitvector_typet
11901188
{
11911189
set_width(width);
11921190
}
1191+
1192+
static void check(
1193+
const typet &type,
1194+
const validation_modet vm = validation_modet::INVARIANT)
1195+
{
1196+
DATA_CHECK(!type.get(ID_width).empty(), "bitvector type must have width");
1197+
}
11931198
};
11941199

11951200
/// Check whether a reference to a typet is a \ref bv_typet.
@@ -1201,11 +1206,6 @@ inline bool can_cast_type<bv_typet>(const typet &type)
12011206
return type.id() == ID_bv;
12021207
}
12031208

1204-
inline void validate_type(const bv_typet &type)
1205-
{
1206-
DATA_INVARIANT(!type.get(ID_width).empty(), "bitvector type must have width");
1207-
}
1208-
12091209
/// \brief Cast a typet to a \ref bv_typet
12101210
///
12111211
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1217,18 +1217,16 @@ inline void validate_type(const bv_typet &type)
12171217
inline const bv_typet &to_bv_type(const typet &type)
12181218
{
12191219
PRECONDITION(can_cast_type<bv_typet>(type));
1220-
const bv_typet &ret = static_cast<const bv_typet &>(type);
1221-
validate_type(ret);
1222-
return ret;
1220+
bv_typet::check(type);
1221+
return static_cast<const bv_typet &>(type);
12231222
}
12241223

12251224
/// \copydoc to_bv_type(const typet &)
12261225
inline bv_typet &to_bv_type(typet &type)
12271226
{
12281227
PRECONDITION(can_cast_type<bv_typet>(type));
1229-
bv_typet &ret = static_cast<bv_typet &>(type);
1230-
validate_type(ret);
1231-
return ret;
1228+
bv_typet::check(type);
1229+
return static_cast<bv_typet &>(type);
12321230
}
12331231

12341232
/// Fixed-width bit-vector with unsigned binary interpretation
@@ -1301,6 +1299,14 @@ class signedbv_typet:public bitvector_typet
13011299
constant_exprt smallest_expr() const;
13021300
constant_exprt zero_expr() const;
13031301
constant_exprt largest_expr() const;
1302+
1303+
static void check(
1304+
const typet &type,
1305+
const validation_modet vm = validation_modet::INVARIANT)
1306+
{
1307+
DATA_CHECK(
1308+
!type.get(ID_width).empty(), "signed bitvector type must have width");
1309+
}
13041310
};
13051311

13061312
/// Check whether a reference to a typet is a \ref signedbv_typet.
@@ -1312,12 +1318,6 @@ inline bool can_cast_type<signedbv_typet>(const typet &type)
13121318
return type.id() == ID_signedbv;
13131319
}
13141320

1315-
inline void validate_type(const signedbv_typet &type)
1316-
{
1317-
DATA_INVARIANT(
1318-
!type.get(ID_width).empty(), "signed bitvector type must have width");
1319-
}
1320-
13211321
/// \brief Cast a typet to a \ref signedbv_typet
13221322
///
13231323
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1329,18 +1329,16 @@ inline void validate_type(const signedbv_typet &type)
13291329
inline const signedbv_typet &to_signedbv_type(const typet &type)
13301330
{
13311331
PRECONDITION(can_cast_type<signedbv_typet>(type));
1332-
const signedbv_typet &ret = static_cast<const signedbv_typet &>(type);
1333-
validate_type(ret);
1334-
return ret;
1332+
signedbv_typet::check(type);
1333+
return static_cast<const signedbv_typet &>(type);
13351334
}
13361335

13371336
/// \copydoc to_signedbv_type(const typet &)
13381337
inline signedbv_typet &to_signedbv_type(typet &type)
13391338
{
13401339
PRECONDITION(can_cast_type<signedbv_typet>(type));
1341-
signedbv_typet &ret = static_cast<signedbv_typet &>(type);
1342-
validate_type(ret);
1343-
return ret;
1340+
signedbv_typet::check(type);
1341+
return static_cast<signedbv_typet &>(type);
13441342
}
13451343

13461344
/// Fixed-width bit-vector with signed fixed-point interpretation
@@ -1365,6 +1363,14 @@ class fixedbv_typet:public bitvector_typet
13651363
{
13661364
set(ID_integer_bits, b);
13671365
}
1366+
1367+
static void check(
1368+
const typet &type,
1369+
const validation_modet vm = validation_modet::INVARIANT)
1370+
{
1371+
DATA_CHECK(
1372+
!type.get(ID_width).empty(), "fixed bitvector type must have width");
1373+
}
13681374
};
13691375

13701376
/// Check whether a reference to a typet is a \ref fixedbv_typet.
@@ -1376,12 +1382,6 @@ inline bool can_cast_type<fixedbv_typet>(const typet &type)
13761382
return type.id() == ID_fixedbv;
13771383
}
13781384

1379-
inline void validate_type(const fixedbv_typet &type)
1380-
{
1381-
DATA_INVARIANT(
1382-
!type.get(ID_width).empty(), "fixed bitvector type must have width");
1383-
}
1384-
13851385
/// \brief Cast a typet to a \ref fixedbv_typet
13861386
///
13871387
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1393,18 +1393,16 @@ inline void validate_type(const fixedbv_typet &type)
13931393
inline const fixedbv_typet &to_fixedbv_type(const typet &type)
13941394
{
13951395
PRECONDITION(can_cast_type<fixedbv_typet>(type));
1396-
const fixedbv_typet &ret = static_cast<const fixedbv_typet &>(type);
1397-
validate_type(ret);
1398-
return ret;
1396+
fixedbv_typet::check(type);
1397+
return static_cast<const fixedbv_typet &>(type);
13991398
}
14001399

14011400
/// \copydoc to_fixedbv_type(const typet &)
14021401
inline fixedbv_typet &to_fixedbv_type(typet &type)
14031402
{
14041403
PRECONDITION(can_cast_type<fixedbv_typet>(type));
1405-
fixedbv_typet &ret = static_cast<fixedbv_typet &>(type);
1406-
validate_type(ret);
1407-
return ret;
1404+
fixedbv_typet::check(type);
1405+
return static_cast<fixedbv_typet &>(type);
14081406
}
14091407

14101408
/// Fixed-width bit-vector with IEEE floating-point interpretation
@@ -1427,6 +1425,14 @@ class floatbv_typet:public bitvector_typet
14271425
{
14281426
set(ID_f, b);
14291427
}
1428+
1429+
static void check(
1430+
const typet &type,
1431+
const validation_modet vm = validation_modet::INVARIANT)
1432+
{
1433+
DATA_CHECK(
1434+
!type.get(ID_width).empty(), "float bitvector type must have width");
1435+
}
14301436
};
14311437

14321438
/// Check whether a reference to a typet is a \ref floatbv_typet.
@@ -1438,12 +1444,6 @@ inline bool can_cast_type<floatbv_typet>(const typet &type)
14381444
return type.id() == ID_floatbv;
14391445
}
14401446

1441-
inline void validate_type(const floatbv_typet &type)
1442-
{
1443-
DATA_INVARIANT(
1444-
!type.get(ID_width).empty(), "float bitvector type must have width");
1445-
}
1446-
14471447
/// \brief Cast a typet to a \ref floatbv_typet
14481448
///
14491449
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1455,18 +1455,16 @@ inline void validate_type(const floatbv_typet &type)
14551455
inline const floatbv_typet &to_floatbv_type(const typet &type)
14561456
{
14571457
PRECONDITION(can_cast_type<floatbv_typet>(type));
1458-
const floatbv_typet &ret = static_cast<const floatbv_typet &>(type);
1459-
validate_type(ret);
1460-
return ret;
1458+
floatbv_typet::check(type);
1459+
return static_cast<const floatbv_typet &>(type);
14611460
}
14621461

14631462
/// \copydoc to_floatbv_type(const typet &)
14641463
inline floatbv_typet &to_floatbv_type(typet &type)
14651464
{
14661465
PRECONDITION(can_cast_type<floatbv_typet>(type));
1467-
floatbv_typet &ret = static_cast<floatbv_typet &>(type);
1468-
validate_type(ret);
1469-
return ret;
1466+
floatbv_typet::check(type);
1467+
return static_cast<floatbv_typet &>(type);
14701468
}
14711469

14721470
/// Type for C bit fields
@@ -1530,6 +1528,13 @@ class pointer_typet:public bitvector_typet
15301528
{
15311529
return signedbv_typet(get_width());
15321530
}
1531+
1532+
static void check(
1533+
const typet &type,
1534+
const validation_modet vm = validation_modet::INVARIANT)
1535+
{
1536+
DATA_CHECK(!type.get(ID_width).empty(), "pointer must have width");
1537+
}
15331538
};
15341539

15351540
/// Check whether a reference to a typet is a \ref pointer_typet.
@@ -1541,11 +1546,6 @@ inline bool can_cast_type<pointer_typet>(const typet &type)
15411546
return type.id() == ID_pointer;
15421547
}
15431548

1544-
inline void validate_type(const pointer_typet &type)
1545-
{
1546-
DATA_INVARIANT(!type.get(ID_width).empty(), "pointer must have width");
1547-
}
1548-
15491549
/// \brief Cast a typet to a \ref pointer_typet
15501550
///
15511551
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1557,18 +1557,16 @@ inline void validate_type(const pointer_typet &type)
15571557
inline const pointer_typet &to_pointer_type(const typet &type)
15581558
{
15591559
PRECONDITION(can_cast_type<pointer_typet>(type));
1560-
const pointer_typet &ret = static_cast<const pointer_typet &>(type);
1561-
validate_type(ret);
1562-
return ret;
1560+
pointer_typet::check(type);
1561+
return static_cast<const pointer_typet &>(type);
15631562
}
15641563

15651564
/// \copydoc to_pointer_type(const typet &)
15661565
inline pointer_typet &to_pointer_type(typet &type)
15671566
{
15681567
PRECONDITION(can_cast_type<pointer_typet>(type));
1569-
pointer_typet &ret = static_cast<pointer_typet &>(type);
1570-
validate_type(ret);
1571-
return ret;
1568+
pointer_typet::check(type);
1569+
return static_cast<pointer_typet &>(type);
15721570
}
15731571

15741572
/// The reference type
@@ -1628,6 +1626,13 @@ class c_bool_typet:public bitvector_typet
16281626
bitvector_typet(ID_c_bool, width)
16291627
{
16301628
}
1629+
1630+
static void check(
1631+
const typet &type,
1632+
const validation_modet vm = validation_modet::INVARIANT)
1633+
{
1634+
DATA_CHECK(!type.get(ID_width).empty(), "C bool type must have width");
1635+
}
16311636
};
16321637

16331638
/// Check whether a reference to a typet is a \ref c_bool_typet.
@@ -1639,11 +1644,6 @@ inline bool can_cast_type<c_bool_typet>(const typet &type)
16391644
return type.id() == ID_c_bool;
16401645
}
16411646

1642-
inline void validate_type(const c_bool_typet &type)
1643-
{
1644-
DATA_INVARIANT(!type.get(ID_width).empty(), "C bool type must have width");
1645-
}
1646-
16471647
/// \brief Cast a typet to a \ref c_bool_typet
16481648
///
16491649
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1655,18 +1655,16 @@ inline void validate_type(const c_bool_typet &type)
16551655
inline const c_bool_typet &to_c_bool_type(const typet &type)
16561656
{
16571657
PRECONDITION(can_cast_type<c_bool_typet>(type));
1658-
const c_bool_typet &ret = static_cast<const c_bool_typet &>(type);
1659-
validate_type(ret);
1660-
return ret;
1658+
c_bool_typet::check(type);
1659+
return static_cast<const c_bool_typet &>(type);
16611660
}
16621661

16631662
/// \copydoc to_c_bool_type(const typet &)
16641663
inline c_bool_typet &to_c_bool_type(typet &type)
16651664
{
16661665
PRECONDITION(can_cast_type<c_bool_typet>(type));
1667-
c_bool_typet &ret = static_cast<c_bool_typet &>(type);
1668-
validate_type(ret);
1669-
return ret;
1666+
c_bool_typet::check(type);
1667+
return static_cast<c_bool_typet &>(type);
16701668
}
16711669

16721670
/// String type

src/util/validate_types.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,34 @@ Author: Daniel Poetzl
2323
template <template <typename, typename> class C, typename... Args>
2424
void call_on_type(const typet &type, Args &&... args)
2525
{
26-
if(type.id() == ID_signedbv)
26+
if(type.id() == ID_bv)
2727
{
28-
CALL_ON_TYPE(signedbv_typet);
28+
CALL_ON_TYPE(bv_typet);
2929
}
3030
else if(type.id() == ID_unsignedbv)
3131
{
3232
CALL_ON_TYPE(unsignedbv_typet);
3333
}
34+
else if(type.id() == ID_signedbv)
35+
{
36+
CALL_ON_TYPE(signedbv_typet);
37+
}
38+
else if(type.id() == ID_fixedbv)
39+
{
40+
CALL_ON_TYPE(fixedbv_typet);
41+
}
42+
else if(type.id() == ID_floatbv)
43+
{
44+
CALL_ON_TYPE(floatbv_typet);
45+
}
46+
else if(type.id() == ID_pointer)
47+
{
48+
CALL_ON_TYPE(pointer_typet);
49+
}
50+
else if(type.id() == ID_c_bool)
51+
{
52+
CALL_ON_TYPE(c_bool_typet);
53+
}
3454
else
3555
{
3656
#ifdef REPORT_UNIMPLEMENTED_TYPE_CHECKS

0 commit comments

Comments
 (0)