Skip to content

Commit 196e7d1

Browse files
authored
Merge pull request #6786 from tautschnig/feature/more-checks
goto-model validation: Validate constant_exprt
2 parents b8f0f14 + 9c12e0f commit 196e7d1

File tree

4 files changed

+100
-1
lines changed

4 files changed

+100
-1
lines changed

regression/cbmc/link_json_symtabs/two.json_symtab

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@
10771077
}
10781078
},
10791079
"value": {
1080-
"id": "00000000000000000000000000000000",
1080+
"id": "0",
10811081
"sub": [
10821082
],
10831083
"namedSub": {

src/util/std_expr.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Author: Daniel Kroening, [email protected]
99
#include "std_expr.h"
1010

1111
#include "namespace.h"
12+
#include "pointer_expr.h"
1213
#include "range.h"
1314

1415
#include <map>
@@ -19,6 +20,33 @@ bool constant_exprt::value_is_zero_string() const
1920
return val.find_first_not_of('0')==std::string::npos;
2021
}
2122

23+
void constant_exprt::check(const exprt &expr, const validation_modet vm)
24+
{
25+
DATA_CHECK(
26+
vm, !expr.has_operands(), "constant expression must not have operands");
27+
28+
DATA_CHECK(
29+
vm,
30+
!can_cast_type<bitvector_typet>(expr.type()) ||
31+
!id2string(to_constant_expr(expr).get_value()).empty(),
32+
"bitvector constant must have a non-empty value");
33+
34+
DATA_CHECK(
35+
vm,
36+
!can_cast_type<bitvector_typet>(expr.type()) ||
37+
can_cast_type<pointer_typet>(expr.type()) ||
38+
id2string(to_constant_expr(expr).get_value())
39+
.find_first_not_of("0123456789ABCDEF") == std::string::npos,
40+
"negative bitvector constant must use two's complement");
41+
42+
DATA_CHECK(
43+
vm,
44+
!can_cast_type<bitvector_typet>(expr.type()) ||
45+
to_constant_expr(expr).get_value() == ID_0 ||
46+
id2string(to_constant_expr(expr).get_value())[0] != '0',
47+
"bitvector constant must not have leading zeros");
48+
}
49+
2250
exprt disjunction(const exprt::operandst &op)
2351
{
2452
if(op.empty())

src/util/std_expr.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ class ternary_exprt : public expr_protectedt
7979
expr.operands().size() == 3,
8080
"ternary expression must have three operands");
8181
}
82+
83+
static void validate(
84+
const exprt &expr,
85+
const namespacet &,
86+
const validation_modet vm = validation_modet::INVARIANT)
87+
{
88+
check(expr, vm);
89+
}
8290
};
8391

8492
/// \brief Cast an exprt to a \ref ternary_exprt
@@ -2294,6 +2302,21 @@ class if_exprt : public ternary_exprt
22942302
{
22952303
return op2();
22962304
}
2305+
2306+
static void check(
2307+
const exprt &expr,
2308+
const validation_modet vm = validation_modet::INVARIANT)
2309+
{
2310+
ternary_exprt::check(expr, vm);
2311+
}
2312+
2313+
static void validate(
2314+
const exprt &expr,
2315+
const namespacet &ns,
2316+
const validation_modet vm = validation_modet::INVARIANT)
2317+
{
2318+
ternary_exprt::validate(expr, ns, vm);
2319+
}
22972320
};
22982321

22992322
template <>
@@ -2563,6 +2586,21 @@ class update_exprt : public ternary_exprt
25632586
{
25642587
return op2();
25652588
}
2589+
2590+
static void check(
2591+
const exprt &expr,
2592+
const validation_modet vm = validation_modet::INVARIANT)
2593+
{
2594+
ternary_exprt::check(expr, vm);
2595+
}
2596+
2597+
static void validate(
2598+
const exprt &expr,
2599+
const namespacet &ns,
2600+
const validation_modet vm = validation_modet::INVARIANT)
2601+
{
2602+
ternary_exprt::validate(expr, ns, vm);
2603+
}
25662604
};
25672605

25682606
template <>
@@ -2848,6 +2886,18 @@ class constant_exprt : public nullary_exprt
28482886
}
28492887

28502888
bool value_is_zero_string() const;
2889+
2890+
static void check(
2891+
const exprt &expr,
2892+
const validation_modet vm = validation_modet::INVARIANT);
2893+
2894+
static void validate(
2895+
const exprt &expr,
2896+
const namespacet &,
2897+
const validation_modet vm = validation_modet::INVARIANT)
2898+
{
2899+
check(expr, vm);
2900+
}
28512901
};
28522902

28532903
template <>

src/util/validate_expressions.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Author: Daniel Poetzl
1313
#include <iostream>
1414
#endif
1515

16+
#include "bitvector_expr.h"
1617
#include "pointer_expr.h"
1718
#include "ssa_expr.h"
1819

@@ -42,6 +43,26 @@ void call_on_expr(const exprt &expr, Args &&... args)
4243
{
4344
CALL_ON_EXPR(dereference_exprt);
4445
}
46+
else if(expr.id() == ID_constant)
47+
{
48+
CALL_ON_EXPR(constant_exprt);
49+
}
50+
else if(expr.id() == ID_if)
51+
{
52+
CALL_ON_EXPR(if_exprt);
53+
}
54+
else if(expr.id() == ID_update)
55+
{
56+
CALL_ON_EXPR(update_exprt);
57+
}
58+
else if(expr.id() == ID_overflow_unary_minus)
59+
{
60+
CALL_ON_EXPR(unary_minus_overflow_exprt);
61+
}
62+
else if(expr.id() == ID_count_leading_zeros)
63+
{
64+
CALL_ON_EXPR(count_leading_zeros_exprt);
65+
}
4566
else
4667
{
4768
#ifdef REPORT_UNIMPLEMENTED_EXPRESSION_CHECKS

0 commit comments

Comments
 (0)