Skip to content

Commit f11196f

Browse files
committed
SMV: lower typecasts between enumeration types
Typecasts between SMV enumeration types (e.g., assigning a variable of type {a, b} to one of type {a, b, c}) are not handled by the flattening. Lower these typecasts to cond expressions that map each source element constant to the corresponding destination element constant.
1 parent fa2c2c0 commit f11196f

3 files changed

Lines changed: 29 additions & 4 deletions

File tree

regression/smv/enums/enum4.desc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE broken-smt-backend
22
enum4.smv
33

44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This fails in the decision procedure.

regression/smv/enums/enum7.desc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE broken-smt-backend
22
enum7.smv
33

44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
The literal is converted incorrectly.

src/smvlang/smv_typecheck.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,33 @@ void smv_typecheckt::lower_node(exprt &expr) const
18151815
auto cond_expr = to_smv_cases_expr(expr).lower();
18161816
expr = std::move(cond_expr);
18171817
}
1818+
else if(expr.id() == ID_typecast)
1819+
{
1820+
auto &typecast_expr = to_typecast_expr(expr);
1821+
auto &src_type = typecast_expr.op().type();
1822+
auto &dest_type = typecast_expr.type();
1823+
1824+
// enumeration to enumeration -- lower to cond
1825+
if(src_type.id() == ID_enumeration && dest_type.id() == ID_smv_enumeration)
1826+
{
1827+
auto lowered_dest_type = dest_type;
1828+
lower(lowered_dest_type);
1829+
1830+
auto &src_elements = to_enumeration_type(src_type).elements();
1831+
1832+
cond_exprt cond_expr{{}, lowered_dest_type};
1833+
for(auto &element : src_elements)
1834+
{
1835+
cond_expr.add_case(
1836+
equal_exprt{
1837+
typecast_expr.op(), constant_exprt{element.id(), src_type}},
1838+
constant_exprt{element.id(), lowered_dest_type});
1839+
}
1840+
1841+
expr = std::move(cond_expr);
1842+
return; // type already set
1843+
}
1844+
}
18181845

18191846
// lower the type
18201847
lower(expr.type());

0 commit comments

Comments
 (0)