Skip to content

Commit bd87ba9

Browse files
author
Enrico Steffinlongo
authored
Merge pull request #7772 from NlightNFotis/enum_in_range
Add lookup for unlowered form in `get_identifier`.
2 parents 892c792 + e698841 commit bd87ba9

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

regression/cbmc/enum_is_in_range/enum_test5.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
enum_test5.c
33
--enum-range-check
44
^EXIT=10$

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,14 +351,24 @@ static optionalt<smt_termt> get_identifier(
351351
&expression_identifiers,
352352
const namespacet &ns)
353353
{
354-
const exprt lowered_expr = lower_enum(expr, ns);
355-
const auto handle_find_result =
356-
expression_handle_identifiers.find(lowered_expr);
354+
// Lookup the non-lowered form first.
355+
const auto handle_find_result = expression_handle_identifiers.find(expr);
357356
if(handle_find_result != expression_handle_identifiers.cend())
358357
return handle_find_result->second;
359-
const auto expr_find_result = expression_identifiers.find(lowered_expr);
358+
const auto expr_find_result = expression_identifiers.find(expr);
360359
if(expr_find_result != expression_identifiers.cend())
361360
return expr_find_result->second;
361+
362+
// If that didn't yield any results, then try the lowered form.
363+
const exprt lowered_expr = lower_enum(expr, ns);
364+
const auto lowered_handle_find_result =
365+
expression_handle_identifiers.find(lowered_expr);
366+
if(lowered_handle_find_result != expression_handle_identifiers.cend())
367+
return lowered_handle_find_result->second;
368+
const auto lowered_expr_find_result =
369+
expression_identifiers.find(lowered_expr);
370+
if(lowered_expr_find_result != expression_identifiers.cend())
371+
return lowered_expr_find_result->second;
362372
return {};
363373
}
364374

unit/solvers/smt2_incremental/encoding/enum_encoding.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static c_enum_typet make_c_enum_type(
2929
return enum_type;
3030
}
3131

32-
constant_exprt create_enum_tag_typed_constant(
32+
static constant_exprt create_enum_tag_typed_constant(
3333
const mp_integer &value,
3434
const c_enum_typet &enum_type,
3535
const c_enum_tag_typet &enum_tag_type)

unit/solvers/smt2_incremental/smt2_incremental_decision_procedure.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
// strings instead of `{?}` being printed. It works because catch uses the
2626
// appropriate overload of `operator<<` where it exists.
2727
#include <util/byte_operators.h>
28+
#include <util/c_types.h>
2829

2930
#include <goto-symex/path_storage.h>
3031
#include <solvers/smt2_incremental/smt_to_smt2_string.h>
@@ -908,3 +909,46 @@ TEST_CASE(
908909
REQUIRE(test.sent_commands == expected_commands);
909910
}
910911
}
912+
913+
static c_enum_typet make_c_enum_type(
914+
const unsignedbv_typet &underlying_type,
915+
unsigned int value_count)
916+
{
917+
c_enum_typet enum_type{underlying_type};
918+
919+
auto &members = enum_type.members();
920+
members.reserve(value_count);
921+
922+
for(unsigned int i = 0; i < value_count; ++i)
923+
{
924+
c_enum_typet::c_enum_membert member;
925+
member.set_identifier("V" + std::to_string(i));
926+
member.set_base_name("V" + std::to_string(i));
927+
member.set_value(integer2bvrep(i, underlying_type.get_width()));
928+
members.push_back(member);
929+
}
930+
return enum_type;
931+
}
932+
933+
TEST_CASE(
934+
"smt2_incremental_decision_proceduret getting enum values back from solver.",
935+
"[core][smt2_incremental]")
936+
{
937+
auto test = decision_procedure_test_environmentt::make();
938+
const unsignedbv_typet enum_underlying_type{32};
939+
const c_enum_typet enum_type = make_c_enum_type(enum_underlying_type, 5);
940+
const type_symbolt enum_symbol{"my_enum", enum_type, ID_C};
941+
test.symbol_table.insert(enum_symbol);
942+
const c_enum_tag_typet enum_tag{enum_symbol.name};
943+
const symbolt enum_value_symbol{"my_enum_value", enum_tag, ID_C};
944+
test.symbol_table.insert(enum_value_symbol);
945+
const auto symbol_expr = enum_value_symbol.symbol_expr();
946+
const auto eq_expr = equal_exprt{symbol_expr, symbol_expr};
947+
948+
test.procedure.handle(eq_expr);
949+
test.mock_responses.push_back(
950+
smt_get_value_responset{{{"B0", smt_bool_literal_termt{true}}}});
951+
auto returned = test.procedure.get(eq_expr);
952+
953+
REQUIRE(returned == constant_exprt{"true", bool_typet{}});
954+
}

0 commit comments

Comments
 (0)