Skip to content

Commit a697de0

Browse files
committed
Simplifier: c_bool (and others) are also bitvector types
Remove simplifier's own is_bitvector_type in favour of using can_cast_type<bitvector_typet>, which will make sure that expressions like bitxor(false, false) over c_bool types gets simplified. Such expressions were seen in Kani (the C front-end would promote bitxor operands to int, and, therefore, not end up in this code path).
1 parent 905033e commit a697de0

File tree

3 files changed

+32
-23
lines changed

3 files changed

+32
-23
lines changed

Diff for: src/util/simplify_expr_class.h

-7
Original file line numberDiff line numberDiff line change
@@ -275,13 +275,6 @@ class simplify_exprt
275275

276276
virtual bool simplify(exprt &expr);
277277

278-
static bool is_bitvector_type(const typet &type)
279-
{
280-
return type.id()==ID_unsignedbv ||
281-
type.id()==ID_signedbv ||
282-
type.id()==ID_bv;
283-
}
284-
285278
protected:
286279
const namespacet &ns;
287280
#ifdef DEBUG_ON_DEMAND

Diff for: src/util/simplify_expr_int.cpp

+15-16
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ simplify_exprt::simplify_minus(const minus_exprt &expr)
662662
simplify_exprt::resultt<>
663663
simplify_exprt::simplify_bitwise(const multi_ary_exprt &expr)
664664
{
665-
if(!is_bitvector_type(expr.type()))
665+
if(!can_cast_type<bitvector_typet>(expr.type()))
666666
return unchanged(expr);
667667

668668
// check if these are really boolean
@@ -838,7 +838,7 @@ simplify_exprt::simplify_extractbit(const extractbit_exprt &expr)
838838
{
839839
const typet &src_type = expr.src().type();
840840

841-
if(!is_bitvector_type(src_type))
841+
if(!can_cast_type<bitvector_typet>(src_type))
842842
return unchanged(expr);
843843

844844
const std::size_t src_bit_width = to_bitvector_type(src_type).get_width();
@@ -869,7 +869,7 @@ simplify_exprt::simplify_concatenation(const concatenation_exprt &expr)
869869

870870
concatenation_exprt new_expr = expr;
871871

872-
if(is_bitvector_type(new_expr.type()))
872+
if(can_cast_type<bitvector_typet>(new_expr.type()))
873873
{
874874
// first, turn bool into bvec[1]
875875
Forall_operands(it, new_expr)
@@ -891,10 +891,10 @@ simplify_exprt::simplify_concatenation(const concatenation_exprt &expr)
891891
exprt &opi = new_expr.operands()[i];
892892
exprt &opn = new_expr.operands()[i + 1];
893893

894-
if(opi.is_constant() &&
895-
opn.is_constant() &&
896-
is_bitvector_type(opi.type()) &&
897-
is_bitvector_type(opn.type()))
894+
if(
895+
opi.is_constant() && opn.is_constant() &&
896+
can_cast_type<bitvector_typet>(opi.type()) &&
897+
can_cast_type<bitvector_typet>(opn.type()))
898898
{
899899
// merge!
900900
const auto &value_i = to_constant_expr(opi).get_value();
@@ -963,12 +963,10 @@ simplify_exprt::simplify_concatenation(const concatenation_exprt &expr)
963963
exprt &opi = new_expr.operands()[i];
964964
exprt &opn = new_expr.operands()[i + 1];
965965

966-
if(opi.is_constant() &&
967-
opn.is_constant() &&
968-
(opi.type().id()==ID_verilog_unsignedbv ||
969-
is_bitvector_type(opi.type())) &&
970-
(opn.type().id()==ID_verilog_unsignedbv ||
971-
is_bitvector_type(opn.type())))
966+
if(
967+
opi.is_constant() && opn.is_constant() &&
968+
can_cast_type<bitvector_typet>(opi.type()) &&
969+
can_cast_type<bitvector_typet>(opn.type()))
972970
{
973971
// merge!
974972
const std::string new_value=
@@ -1001,7 +999,7 @@ simplify_exprt::simplify_concatenation(const concatenation_exprt &expr)
1001999
simplify_exprt::resultt<>
10021000
simplify_exprt::simplify_shifts(const shift_exprt &expr)
10031001
{
1004-
if(!is_bitvector_type(expr.type()))
1002+
if(!can_cast_type<bitvector_typet>(expr.type()))
10051003
return unchanged(expr);
10061004

10071005
const auto distance = numeric_cast<mp_integer>(expr.distance());
@@ -1132,8 +1130,9 @@ simplify_exprt::simplify_extractbits(const extractbits_exprt &expr)
11321130
{
11331131
const typet &op0_type = expr.src().type();
11341132

1135-
if(!is_bitvector_type(op0_type) &&
1136-
!is_bitvector_type(expr.type()))
1133+
if(
1134+
!can_cast_type<bitvector_typet>(op0_type) &&
1135+
!can_cast_type<bitvector_typet>(expr.type()))
11371136
{
11381137
return unchanged(expr);
11391138
}

Diff for: unit/util/simplify_expr.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -554,3 +554,20 @@ TEST_CASE("Simplify inequality", "[core][util]")
554554
REQUIRE(simp == true_exprt{});
555555
}
556556
}
557+
558+
TEST_CASE("Simplify bitxor", "[core][util]")
559+
{
560+
config.set_arch("none");
561+
562+
const symbol_tablet symbol_table;
563+
const namespacet ns(symbol_table);
564+
565+
SECTION("Simplification for c_bool")
566+
{
567+
constant_exprt false_c_bool = from_integer(0, c_bool_type());
568+
569+
REQUIRE(
570+
simplify_expr(bitxor_exprt{false_c_bool, false_c_bool}, ns) ==
571+
false_c_bool);
572+
}
573+
}

0 commit comments

Comments
 (0)