Skip to content

Commit fef7925

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 283bdbc commit fef7925

File tree

3 files changed

+93
-86
lines changed

3 files changed

+93
-86
lines changed

src/util/expr_cast.h

+2-13
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

+69-71
Original file line numberDiff line numberDiff line change
@@ -1003,15 +1003,13 @@ inline bool can_cast_type<code_typet>(const typet &type)
10031003
inline const code_typet &to_code_type(const typet &type)
10041004
{
10051005
PRECONDITION(can_cast_type<code_typet>(type));
1006-
validate_type(type);
10071006
return static_cast<const code_typet &>(type);
10081007
}
10091008

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

@@ -1198,6 +1196,13 @@ class bv_typet:public bitvector_typet
11981196
{
11991197
set_width(width);
12001198
}
1199+
1200+
static void check(
1201+
const typet &type,
1202+
const validation_modet vm = validation_modet::INVARIANT)
1203+
{
1204+
DATA_CHECK(!type.get(ID_width).empty(), "bitvector type must have width");
1205+
}
12011206
};
12021207

12031208
/// Check whether a reference to a typet is a \ref bv_typet.
@@ -1209,11 +1214,6 @@ inline bool can_cast_type<bv_typet>(const typet &type)
12091214
return type.id() == ID_bv;
12101215
}
12111216

1212-
inline void validate_type(const bv_typet &type)
1213-
{
1214-
DATA_INVARIANT(!type.get(ID_width).empty(), "bitvector type must have width");
1215-
}
1216-
12171217
/// \brief Cast a typet to a \ref bv_typet
12181218
///
12191219
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1225,18 +1225,16 @@ inline void validate_type(const bv_typet &type)
12251225
inline const bv_typet &to_bv_type(const typet &type)
12261226
{
12271227
PRECONDITION(can_cast_type<bv_typet>(type));
1228-
const bv_typet &ret = static_cast<const bv_typet &>(type);
1229-
validate_type(ret);
1230-
return ret;
1228+
bv_typet::check(type);
1229+
return static_cast<const bv_typet &>(type);
12311230
}
12321231

12331232
/// \copydoc to_bv_type(const typet &)
12341233
inline bv_typet &to_bv_type(typet &type)
12351234
{
12361235
PRECONDITION(can_cast_type<bv_typet>(type));
1237-
bv_typet &ret = static_cast<bv_typet &>(type);
1238-
validate_type(ret);
1239-
return ret;
1236+
bv_typet::check(type);
1237+
return static_cast<bv_typet &>(type);
12401238
}
12411239

12421240
/// Fixed-width bit-vector with unsigned binary interpretation
@@ -1308,6 +1306,14 @@ class signedbv_typet:public bitvector_typet
13081306
constant_exprt smallest_expr() const;
13091307
constant_exprt zero_expr() const;
13101308
constant_exprt largest_expr() const;
1309+
1310+
static void check(
1311+
const typet &type,
1312+
const validation_modet vm = validation_modet::INVARIANT)
1313+
{
1314+
DATA_CHECK(
1315+
!type.get(ID_width).empty(), "signed bitvector type must have width");
1316+
}
13111317
};
13121318

13131319
/// Check whether a reference to a typet is a \ref signedbv_typet.
@@ -1319,12 +1325,6 @@ inline bool can_cast_type<signedbv_typet>(const typet &type)
13191325
return type.id() == ID_signedbv;
13201326
}
13211327

1322-
inline void validate_type(const signedbv_typet &type)
1323-
{
1324-
DATA_INVARIANT(
1325-
!type.get(ID_width).empty(), "signed bitvector type must have width");
1326-
}
1327-
13281328
/// \brief Cast a typet to a \ref signedbv_typet
13291329
///
13301330
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1336,18 +1336,16 @@ inline void validate_type(const signedbv_typet &type)
13361336
inline const signedbv_typet &to_signedbv_type(const typet &type)
13371337
{
13381338
PRECONDITION(can_cast_type<signedbv_typet>(type));
1339-
const signedbv_typet &ret = static_cast<const signedbv_typet &>(type);
1340-
validate_type(ret);
1341-
return ret;
1339+
signedbv_typet::check(type);
1340+
return static_cast<const signedbv_typet &>(type);
13421341
}
13431342

13441343
/// \copydoc to_signedbv_type(const typet &)
13451344
inline signedbv_typet &to_signedbv_type(typet &type)
13461345
{
13471346
PRECONDITION(can_cast_type<signedbv_typet>(type));
1348-
signedbv_typet &ret = static_cast<signedbv_typet &>(type);
1349-
validate_type(ret);
1350-
return ret;
1347+
signedbv_typet::check(type);
1348+
return static_cast<signedbv_typet &>(type);
13511349
}
13521350

13531351
/// Fixed-width bit-vector with signed fixed-point interpretation
@@ -1372,6 +1370,14 @@ class fixedbv_typet:public bitvector_typet
13721370
{
13731371
set(ID_integer_bits, b);
13741372
}
1373+
1374+
static void check(
1375+
const typet &type,
1376+
const validation_modet vm = validation_modet::INVARIANT)
1377+
{
1378+
DATA_CHECK(
1379+
!type.get(ID_width).empty(), "fixed bitvector type must have width");
1380+
}
13751381
};
13761382

13771383
/// Check whether a reference to a typet is a \ref fixedbv_typet.
@@ -1383,12 +1389,6 @@ inline bool can_cast_type<fixedbv_typet>(const typet &type)
13831389
return type.id() == ID_fixedbv;
13841390
}
13851391

1386-
inline void validate_type(const fixedbv_typet &type)
1387-
{
1388-
DATA_INVARIANT(
1389-
!type.get(ID_width).empty(), "fixed bitvector type must have width");
1390-
}
1391-
13921392
/// \brief Cast a typet to a \ref fixedbv_typet
13931393
///
13941394
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1400,18 +1400,16 @@ inline void validate_type(const fixedbv_typet &type)
14001400
inline const fixedbv_typet &to_fixedbv_type(const typet &type)
14011401
{
14021402
PRECONDITION(can_cast_type<fixedbv_typet>(type));
1403-
const fixedbv_typet &ret = static_cast<const fixedbv_typet &>(type);
1404-
validate_type(ret);
1405-
return ret;
1403+
fixedbv_typet::check(type);
1404+
return static_cast<const fixedbv_typet &>(type);
14061405
}
14071406

14081407
/// \copydoc to_fixedbv_type(const typet &)
14091408
inline fixedbv_typet &to_fixedbv_type(typet &type)
14101409
{
14111410
PRECONDITION(can_cast_type<fixedbv_typet>(type));
1412-
fixedbv_typet &ret = static_cast<fixedbv_typet &>(type);
1413-
validate_type(ret);
1414-
return ret;
1411+
fixedbv_typet::check(type);
1412+
return static_cast<fixedbv_typet &>(type);
14151413
}
14161414

14171415
/// Fixed-width bit-vector with IEEE floating-point interpretation
@@ -1434,6 +1432,14 @@ class floatbv_typet:public bitvector_typet
14341432
{
14351433
set(ID_f, b);
14361434
}
1435+
1436+
static void check(
1437+
const typet &type,
1438+
const validation_modet vm = validation_modet::INVARIANT)
1439+
{
1440+
DATA_CHECK(
1441+
!type.get(ID_width).empty(), "float bitvector type must have width");
1442+
}
14371443
};
14381444

14391445
/// Check whether a reference to a typet is a \ref floatbv_typet.
@@ -1445,12 +1451,6 @@ inline bool can_cast_type<floatbv_typet>(const typet &type)
14451451
return type.id() == ID_floatbv;
14461452
}
14471453

1448-
inline void validate_type(const floatbv_typet &type)
1449-
{
1450-
DATA_INVARIANT(
1451-
!type.get(ID_width).empty(), "float bitvector type must have width");
1452-
}
1453-
14541454
/// \brief Cast a typet to a \ref floatbv_typet
14551455
///
14561456
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1462,18 +1462,16 @@ inline void validate_type(const floatbv_typet &type)
14621462
inline const floatbv_typet &to_floatbv_type(const typet &type)
14631463
{
14641464
PRECONDITION(can_cast_type<floatbv_typet>(type));
1465-
const floatbv_typet &ret = static_cast<const floatbv_typet &>(type);
1466-
validate_type(ret);
1467-
return ret;
1465+
floatbv_typet::check(type);
1466+
return static_cast<const floatbv_typet &>(type);
14681467
}
14691468

14701469
/// \copydoc to_floatbv_type(const typet &)
14711470
inline floatbv_typet &to_floatbv_type(typet &type)
14721471
{
14731472
PRECONDITION(can_cast_type<floatbv_typet>(type));
1474-
floatbv_typet &ret = static_cast<floatbv_typet &>(type);
1475-
validate_type(ret);
1476-
return ret;
1473+
floatbv_typet::check(type);
1474+
return static_cast<floatbv_typet &>(type);
14771475
}
14781476

14791477
/// Type for C bit fields
@@ -1537,6 +1535,13 @@ class pointer_typet:public bitvector_typet
15371535
{
15381536
return signedbv_typet(get_width());
15391537
}
1538+
1539+
static void check(
1540+
const typet &type,
1541+
const validation_modet vm = validation_modet::INVARIANT)
1542+
{
1543+
DATA_CHECK(!type.get(ID_width).empty(), "pointer must have width");
1544+
}
15401545
};
15411546

15421547
/// Check whether a reference to a typet is a \ref pointer_typet.
@@ -1548,11 +1553,6 @@ inline bool can_cast_type<pointer_typet>(const typet &type)
15481553
return type.id() == ID_pointer;
15491554
}
15501555

1551-
inline void validate_type(const pointer_typet &type)
1552-
{
1553-
DATA_INVARIANT(!type.get(ID_width).empty(), "pointer must have width");
1554-
}
1555-
15561556
/// \brief Cast a typet to a \ref pointer_typet
15571557
///
15581558
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1564,18 +1564,16 @@ inline void validate_type(const pointer_typet &type)
15641564
inline const pointer_typet &to_pointer_type(const typet &type)
15651565
{
15661566
PRECONDITION(can_cast_type<pointer_typet>(type));
1567-
const pointer_typet &ret = static_cast<const pointer_typet &>(type);
1568-
validate_type(ret);
1569-
return ret;
1567+
pointer_typet::check(type);
1568+
return static_cast<const pointer_typet &>(type);
15701569
}
15711570

15721571
/// \copydoc to_pointer_type(const typet &)
15731572
inline pointer_typet &to_pointer_type(typet &type)
15741573
{
15751574
PRECONDITION(can_cast_type<pointer_typet>(type));
1576-
pointer_typet &ret = static_cast<pointer_typet &>(type);
1577-
validate_type(ret);
1578-
return ret;
1575+
pointer_typet::check(type);
1576+
return static_cast<pointer_typet &>(type);
15791577
}
15801578

15811579
/// The reference type
@@ -1635,6 +1633,13 @@ class c_bool_typet:public bitvector_typet
16351633
bitvector_typet(ID_c_bool, width)
16361634
{
16371635
}
1636+
1637+
static void check(
1638+
const typet &type,
1639+
const validation_modet vm = validation_modet::INVARIANT)
1640+
{
1641+
DATA_CHECK(!type.get(ID_width).empty(), "C bool type must have width");
1642+
}
16381643
};
16391644

16401645
/// Check whether a reference to a typet is a \ref c_bool_typet.
@@ -1646,11 +1651,6 @@ inline bool can_cast_type<c_bool_typet>(const typet &type)
16461651
return type.id() == ID_c_bool;
16471652
}
16481653

1649-
inline void validate_type(const c_bool_typet &type)
1650-
{
1651-
DATA_INVARIANT(!type.get(ID_width).empty(), "C bool type must have width");
1652-
}
1653-
16541654
/// \brief Cast a typet to a \ref c_bool_typet
16551655
///
16561656
/// This is an unchecked conversion. \a type must be known to be \ref
@@ -1662,18 +1662,16 @@ inline void validate_type(const c_bool_typet &type)
16621662
inline const c_bool_typet &to_c_bool_type(const typet &type)
16631663
{
16641664
PRECONDITION(can_cast_type<c_bool_typet>(type));
1665-
const c_bool_typet &ret = static_cast<const c_bool_typet &>(type);
1666-
validate_type(ret);
1667-
return ret;
1665+
c_bool_typet::check(type);
1666+
return static_cast<const c_bool_typet &>(type);
16681667
}
16691668

16701669
/// \copydoc to_c_bool_type(const typet &)
16711670
inline c_bool_typet &to_c_bool_type(typet &type)
16721671
{
16731672
PRECONDITION(can_cast_type<c_bool_typet>(type));
1674-
c_bool_typet &ret = static_cast<c_bool_typet &>(type);
1675-
validate_type(ret);
1676-
return ret;
1673+
c_bool_typet::check(type);
1674+
return static_cast<c_bool_typet &>(type);
16771675
}
16781676

16791677
/// String type

src/util/validate_types.cpp

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

0 commit comments

Comments
 (0)