Skip to content

Commit 24a3d2a

Browse files
author
Daniel Kroening
authored
Merge pull request #4904 from diffblue/simplify_cast_from_boolean
simplifier: eliminate casts from bool to number
2 parents 3ad2a27 + ccfba0b commit 24a3d2a

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

jbmc/unit/util/simplify_expr.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ void test_unnecessary_cast(const typet &type)
4747
REQUIRE(simplified.type()==java_int_type());
4848
}
4949

50+
// casts from boolean get rewritten to ?:
51+
if(type == java_boolean_type())
52+
{
53+
const exprt simplified = simplify_expr(
54+
typecast_exprt(symbol_exprt("foo", java_int_type()), type),
55+
namespacet(symbol_tablet()));
56+
57+
REQUIRE(simplified.id() == ID_if);
58+
REQUIRE(simplified.type() == type);
59+
}
60+
else
5061
{
5162
const exprt simplified=simplify_expr(
5263
typecast_exprt(symbol_exprt("foo", java_int_type()), type),

src/util/simplify_expr.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,19 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
576576
return std::move(inequality);
577577
}
578578

579+
// eliminate casts from proper bool
580+
if(
581+
op_type.id() == ID_bool &&
582+
(expr_type.id() == ID_signedbv || expr_type.id() == ID_unsignedbv ||
583+
expr_type.id() == ID_c_bool || expr_type.id() == ID_c_bit_field))
584+
{
585+
// rewrite (T)(bool) to bool?1:0
586+
auto one = from_integer(1, expr_type);
587+
auto zero = from_integer(0, expr_type);
588+
exprt new_expr = if_exprt(expr.op(), std::move(one), std::move(zero));
589+
return changed(simplify_rec(new_expr)); // recursive call
590+
}
591+
579592
// circular casts through types shorter than `int`
580593
if(op_type == signedbv_typet(32) && expr.op().id() == ID_typecast)
581594
{

unit/util/simplify_expr.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,57 @@ TEST_CASE("Simplify pointer_object equality", "[core][util]")
244244

245245
REQUIRE(simp.is_true());
246246
}
247+
248+
TEST_CASE("Simplify cast from bool", "[core][util]")
249+
{
250+
symbol_tablet symbol_table;
251+
namespacet ns(symbol_table);
252+
253+
{
254+
// this checks that ((int)B)==1 turns into B
255+
exprt B = symbol_exprt("B", bool_typet());
256+
exprt comparison = equal_exprt(
257+
typecast_exprt(B, signedbv_typet(32)),
258+
from_integer(1, signedbv_typet(32)));
259+
260+
exprt simp = simplify_expr(comparison, ns);
261+
262+
REQUIRE(simp == B);
263+
}
264+
265+
{
266+
// this checks that ((int)B)==0 turns into !B
267+
exprt B = symbol_exprt("B", bool_typet());
268+
exprt comparison = equal_exprt(
269+
typecast_exprt(B, signedbv_typet(32)),
270+
from_integer(0, signedbv_typet(32)));
271+
272+
exprt simp = simplify_expr(comparison, ns);
273+
274+
REQUIRE(simp == not_exprt(B));
275+
}
276+
277+
{
278+
// this checks that ((int)B)!=1 turns into !B
279+
exprt B = symbol_exprt("B", bool_typet());
280+
exprt comparison = notequal_exprt(
281+
typecast_exprt(B, signedbv_typet(32)),
282+
from_integer(1, signedbv_typet(32)));
283+
284+
exprt simp = simplify_expr(comparison, ns);
285+
286+
REQUIRE(simp == not_exprt(B));
287+
}
288+
289+
{
290+
// this checks that ((int)B)!=0 turns into B
291+
exprt B = symbol_exprt("B", bool_typet());
292+
exprt comparison = notequal_exprt(
293+
typecast_exprt(B, signedbv_typet(32)),
294+
from_integer(0, signedbv_typet(32)));
295+
296+
exprt simp = simplify_expr(comparison, ns);
297+
298+
REQUIRE(simp == B);
299+
}
300+
}

0 commit comments

Comments
 (0)