Skip to content

Commit deb4e1a

Browse files
Merge pull request #7952 from thomasspriggs/tas/smt_lower_symbol_values
Add missing lowering of symbol values in new SMT backend
2 parents a010865 + 4ac6f7d commit deb4e1a

File tree

4 files changed

+108
-2
lines changed

4 files changed

+108
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <assert.h>
2+
#include <stdint.h>
3+
4+
struct F
5+
{
6+
uint16_t w;
7+
uint16_t x;
8+
};
9+
10+
static struct F a = {0xdeadbeef};
11+
static struct F b = {0xbeefdead};
12+
13+
int main()
14+
{
15+
struct F *p;
16+
if(nondet_int())
17+
p = &a;
18+
else
19+
p = &b;
20+
21+
assert(p->w != 0xdead);
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
struct_static_init.c
3+
4+
Passing problem to incremental SMT2 solving
5+
line \d+ assertion p->w != 0xdead: FAILURE
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
--
10+
Test that statically initialised variables of struct type (whose values are
11+
stored in the symbolt_table) are lowered correctly.

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,11 @@ void smt2_incremental_decision_proceduret::define_dependent_functions(
223223
}
224224
else
225225
{
226-
if(push_dependencies_needed(symbol->value))
226+
const exprt lowered = lower(symbol->value);
227+
if(push_dependencies_needed(lowered))
227228
continue;
228229
const smt_define_function_commandt function{
229-
symbol->name, {}, convert_expr_to_smt(symbol->value)};
230+
symbol->name, {}, convert_expr_to_smt(lowered)};
230231
expression_identifiers.emplace(*symbol_expr, function.identifier());
231232
identifier_table.emplace(identifier, function.identifier());
232233
solver_process->send(function);

unit/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

+72
Original file line numberDiff line numberDiff line change
@@ -1144,3 +1144,75 @@ TEST_CASE(
11441144
smt_get_value_commandt{expected_foo}};
11451145
CHECK(test.sent_commands == expected_get_commands);
11461146
}
1147+
1148+
TEST_CASE(
1149+
"smt2_incremental_decision_proceduret getting value of struct-symbols with "
1150+
"value in the symbol table",
1151+
"[core][util][expr_initializer]")
1152+
{
1153+
auto test = decision_procedure_test_environmentt::make();
1154+
1155+
const struct_union_typet::componentst inner_struct_type_components{
1156+
{"foo", signedbv_typet{32}}, {"bar", unsignedbv_typet{16}}};
1157+
const struct_typet inner_struct_type{inner_struct_type_components};
1158+
const type_symbolt inner_struct_type_symbol{
1159+
"inner_struct_type_symbol", inner_struct_type, ID_C};
1160+
test.symbol_table.insert(inner_struct_type_symbol);
1161+
const struct_tag_typet inner_struct_type_tag{inner_struct_type_symbol.name};
1162+
1163+
const struct_union_typet::componentst struct_components{
1164+
{"fizz", c_bool_type()}, {"bar", inner_struct_type_tag}};
1165+
const struct_typet struct_type{struct_components};
1166+
const type_symbolt struct_type_symbol{
1167+
"struct_type_symbol", struct_type, ID_C};
1168+
test.symbol_table.insert(struct_type_symbol);
1169+
const struct_tag_typet struct_tag{struct_type_symbol.name};
1170+
1171+
const exprt::operandst inner_struct_operands{
1172+
from_integer(10, signedbv_typet{32}),
1173+
from_integer(23, unsignedbv_typet{16})};
1174+
const struct_exprt inner_struct_expr{
1175+
inner_struct_operands, inner_struct_type_tag};
1176+
symbolt inner_symbol_with_value{
1177+
"inner_symbol_with_value", inner_struct_type_tag, ID_C};
1178+
inner_symbol_with_value.value = inner_struct_expr;
1179+
test.symbol_table.insert(inner_symbol_with_value);
1180+
const symbol_exprt inner_symbol_expr{
1181+
inner_symbol_with_value.name, inner_symbol_with_value.type};
1182+
1183+
const exprt::operandst struct_operands{
1184+
from_integer(1, c_bool_type()), inner_symbol_expr};
1185+
const struct_exprt struct_expr{struct_operands, struct_tag};
1186+
1187+
symbolt symbol_with_value{"symbol_with_value", struct_tag, ID_C};
1188+
symbol_with_value.value = struct_expr;
1189+
test.symbol_table.insert(symbol_with_value);
1190+
1191+
const symbol_exprt symbol_expr{
1192+
symbol_with_value.name, symbol_with_value.type};
1193+
1194+
const equal_exprt equal_expr{symbol_expr, symbol_expr};
1195+
1196+
test.sent_commands.clear();
1197+
test.procedure.set_to(equal_expr, true);
1198+
1199+
std::vector<smt_commandt> expected_commands{
1200+
smt_define_function_commandt(
1201+
inner_symbol_with_value.name,
1202+
{},
1203+
smt_bit_vector_theoryt::concat(
1204+
smt_bit_vector_constant_termt{10, 32},
1205+
smt_bit_vector_constant_termt{23, 16})),
1206+
smt_define_function_commandt(
1207+
symbol_with_value.name,
1208+
{},
1209+
smt_bit_vector_theoryt::concat(
1210+
smt_bit_vector_constant_termt{1, config.ansi_c.bool_width},
1211+
smt_identifier_termt{
1212+
inner_symbol_with_value.name, smt_bit_vector_sortt{48}})),
1213+
smt_assert_commandt{smt_core_theoryt::equal(
1214+
smt_identifier_termt{symbol_with_value.name, smt_bit_vector_sortt{56}},
1215+
smt_identifier_termt{symbol_with_value.name, smt_bit_vector_sortt{56}})}};
1216+
1217+
CHECK(test.sent_commands == expected_commands);
1218+
}

0 commit comments

Comments
 (0)