Skip to content

Commit 1858332

Browse files
committed
Add nondet_padding expression
This data structure will be used to allow encoding/lowering passes to insert padding bitvectors with non deteriministic values. Unlike the SAT decision procedures, generating an SMT formula for nondet padding will require a corresponding parameter-less function to be defined. This placeholder expression is intended to be inserted in lowering passes and then substituted at the point of term generation. Note that it doesn't quite make sense to use symbols for this as the decision procedure doesn't have mutable symbol table access and adding an extra decision procedure symbol table would have other complications.
1 parent 99c5402 commit 1858332

File tree

3 files changed

+85
-0
lines changed

3 files changed

+85
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Author: Diffblue Ltd.
2+
3+
/// \file
4+
/// Expressions for use in incremental SMT2 decision procedure
5+
6+
#ifndef CPROVER_SOLVERS_SMT2_INCREMENTAL_ENCODING_NONDET_PADDING_H
7+
#define CPROVER_SOLVERS_SMT2_INCREMENTAL_ENCODING_NONDET_PADDING_H
8+
9+
#include <util/bitvector_types.h>
10+
#include <util/expr.h>
11+
#include <util/invariant.h>
12+
13+
class nondet_padding_exprt;
14+
void validate_expr(const nondet_padding_exprt &padding);
15+
16+
const irep_idt ID_nondet_padding = "nondet_padding";
17+
18+
class nondet_padding_exprt : public expr_protectedt
19+
{
20+
public:
21+
explicit nondet_padding_exprt(typet type)
22+
: expr_protectedt{ID_nondet_padding, std::move(type)}
23+
{
24+
validate_expr(*this);
25+
}
26+
};
27+
28+
template <>
29+
inline bool can_cast_expr<nondet_padding_exprt>(const exprt &base)
30+
{
31+
return base.id() == ID_nondet_padding;
32+
}
33+
34+
inline void validate_expr(const nondet_padding_exprt &padding)
35+
{
36+
INVARIANT(
37+
can_cast_type<bv_typet>(padding.type()),
38+
"Nondet padding is expected to pad a bit vector type.");
39+
}
40+
41+
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_ENCODING_NONDET_PADDING_H

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ SRC += analyses/ai/ai.cpp \
117117
solvers/smt2_incremental/smt_to_smt2_string.cpp \
118118
solvers/smt2_incremental/encoding/struct_encoding.cpp \
119119
solvers/smt2_incremental/encoding/enum_encoding.cpp \
120+
solvers/smt2_incremental/encoding/nondet_padding.cpp \
120121
solvers/smt2_incremental/theories/smt_array_theory.cpp \
121122
solvers/smt2_incremental/theories/smt_bit_vector_theory.cpp \
122123
solvers/smt2_incremental/theories/smt_core_theory.cpp \
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Author: Diffblue Ltd.
2+
3+
#include <util/expr_cast.h>
4+
#include <util/std_expr.h>
5+
6+
#include <solvers/smt2_incremental/encoding/nondet_padding.h>
7+
#include <testing-utils/invariant.h>
8+
#include <testing-utils/use_catch.h>
9+
10+
TEST_CASE("Nondet padding expression", "[core][smt2_incremental]")
11+
{
12+
const bv_typet type{8};
13+
const exprt padding = nondet_padding_exprt{type};
14+
SECTION("Valid usage")
15+
{
16+
REQUIRE(padding.type() == type);
17+
REQUIRE(nullptr != expr_try_dynamic_cast<nondet_padding_exprt>(padding));
18+
}
19+
const auto type_error = invariant_failure_containing(
20+
"Nondet padding is expected to pad a bit vector type.");
21+
SECTION("Failed downcasts")
22+
{
23+
const exprt not_padding = symbol_exprt{"foo", empty_typet{}};
24+
REQUIRE(
25+
nullptr == expr_try_dynamic_cast<nondet_padding_exprt>(not_padding));
26+
const exprt wrong_type = [&]() {
27+
exprt padding = nondet_padding_exprt{type};
28+
padding.type() = empty_typet{};
29+
return padding;
30+
}();
31+
cbmc_invariants_should_throwt invariants_throw;
32+
CHECK_THROWS_MATCHES(
33+
expr_checked_cast<nondet_padding_exprt>(wrong_type),
34+
invariant_failedt,
35+
type_error);
36+
}
37+
SECTION("Construction with incorrect type")
38+
{
39+
cbmc_invariants_should_throwt invariants_throw;
40+
CHECK_THROWS_MATCHES(
41+
nondet_padding_exprt{empty_typet{}}, invariant_failedt, type_error);
42+
}
43+
}

0 commit comments

Comments
 (0)