Skip to content

Commit eca493e

Browse files
Merge pull request #7754 from thomasspriggs/tas/fix_single_member_structs
Fix support for single member structs in incremental SMT decision procedure
2 parents e56c494 + 8fc63dc commit eca493e

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

regression/cbmc/Initialization7/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
CORE new-smt-backend
22
main.c
33

44
^EXIT=10$

src/solvers/smt2_incremental/struct_encoding.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ typet struct_encodingt::encode(typet type) const
3232
work_queue.pop();
3333
if(const auto struct_tag = type_try_dynamic_cast<struct_tag_typet>(current))
3434
{
35-
current = bv_typet{(*boolbv_width)(*struct_tag)};
35+
const auto width = (*boolbv_width)(*struct_tag);
36+
if(width == 0)
37+
UNIMPLEMENTED_FEATURE("support for zero bit width structs.");
38+
current = bv_typet{width};
3639
}
3740
if(const auto array = type_try_dynamic_cast<array_typet>(current))
3841
{
@@ -44,6 +47,11 @@ typet struct_encodingt::encode(typet type) const
4447

4548
static exprt encode(const struct_exprt &struct_expr)
4649
{
50+
INVARIANT(
51+
!struct_expr.operands().empty(),
52+
"empty structs may not be encoded into SMT terms.");
53+
if(struct_expr.operands().size() == 1)
54+
return struct_expr.operands().front();
4755
return concatenation_exprt{struct_expr.operands(), struct_expr.type()};
4856
}
4957

unit/solvers/smt2_incremental/struct_encoding.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,35 @@ TEST_CASE("struct encoding of expressions", "[core][smt2_incremental]")
105105
REQUIRE(test.struct_encoding.encode(struct_expr) == expected_result);
106106
}
107107
}
108+
109+
TEST_CASE(
110+
"encoding of single member struct expressions",
111+
"[core][smt2_incremental]")
112+
{
113+
const struct_union_typet::componentst component_types{
114+
{"eggs", signedbv_typet{32}}};
115+
const type_symbolt type_symbol{"foot", struct_typet{component_types}, ID_C};
116+
auto test = struct_encoding_test_environmentt::make();
117+
test.symbol_table.insert(type_symbol);
118+
const struct_tag_typet struct_tag{type_symbol.name};
119+
const symbolt struct_value_symbol{"foo", struct_tag, ID_C};
120+
test.symbol_table.insert(struct_value_symbol);
121+
const auto symbol_expr = struct_value_symbol.symbol_expr();
122+
const auto symbol_expr_as_bv = symbol_exprt{"foo", bv_typet{32}};
123+
SECTION("struct typed symbol expression")
124+
{
125+
REQUIRE(test.struct_encoding.encode(symbol_expr) == symbol_expr_as_bv);
126+
}
127+
SECTION("struct equality expression")
128+
{
129+
const auto struct_equal = equal_exprt{symbol_expr, symbol_expr};
130+
const auto bv_equal = equal_exprt{symbol_expr_as_bv, symbol_expr_as_bv};
131+
REQUIRE(test.struct_encoding.encode(struct_equal) == bv_equal);
132+
}
133+
SECTION("expression for a struct from (single item) list of components")
134+
{
135+
const auto dozen = from_integer(12, signedbv_typet{32});
136+
const struct_exprt struct_expr{{dozen}, struct_tag};
137+
REQUIRE(test.struct_encoding.encode(struct_expr) == dozen);
138+
}
139+
}

0 commit comments

Comments
 (0)