Skip to content

Commit 8f4f2ec

Browse files
author
Thomas Kiley
authored
Merge pull request #1473 from reuk/reuk/simplify-expr-fixup
Simplify a broader range of java primitive types
2 parents 1ad89a0 + 24f9867 commit 8f4f2ec

File tree

2 files changed

+95
-23
lines changed

2 files changed

+95
-23
lines changed

src/util/simplify_expr.cpp

+16-9
Original file line numberDiff line numberDiff line change
@@ -237,22 +237,29 @@ bool simplify_exprt::simplify_typecast(exprt &expr)
237237
return false;
238238
}
239239

240-
// eliminate casts to _Bool
241-
if(expr_type.id()==ID_c_bool &&
242-
op_type.id()!=ID_bool)
243-
{
244-
// casts from boolean to a signed int and back:
245-
// (boolean)(int)boolean -> boolean
246-
if(expr.op0().id()==ID_typecast && op_type.id()==ID_signedbv)
240+
// circular casts through types shorter than `int`
241+
if(op_type==signedbv_typet(32) &&
242+
expr.op0().id()==ID_typecast)
243+
{
244+
if(expr_type==c_bool_typet(8) ||
245+
expr_type==signedbv_typet(8) ||
246+
expr_type==signedbv_typet(16) ||
247+
expr_type==unsignedbv_typet(16))
247248
{
248-
const auto &typecast=to_typecast_expr(expr.op0());
249-
if(typecast.op().type().id()==ID_c_bool)
249+
// We checked that the id was ID_typecast in the enclosing `if`
250+
const auto &typecast=expr_checked_cast<typecast_exprt>(expr.op0());
251+
if(typecast.op().type()==expr_type)
250252
{
251253
expr=typecast.op0();
252254
return false;
253255
}
254256
}
257+
}
255258

259+
// eliminate casts to _Bool
260+
if(expr_type.id()==ID_c_bool &&
261+
op_type.id()!=ID_bool)
262+
{
256263
// rewrite (_Bool)x to (_Bool)(x!=0)
257264
binary_relation_exprt inequality;
258265
inequality.id(op_type.id()==ID_floatbv?ID_ieee_float_notequal:ID_notequal);

unit/util/simplify_expr.cpp

+79-14
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,87 @@ TEST_CASE("Simplify const pointer offset")
6161
REQUIRE(offset_value==1234);
6262
}
6363

64-
TEST_CASE("Simplify Java boolean -> int -> boolean casts")
64+
namespace
65+
{
66+
67+
void test_unnecessary_cast(const typet &type)
6568
{
6669
config.set_arch("none");
6770

68-
const exprt simplified=simplify_expr(
69-
typecast_exprt(
71+
WHEN("The casts can be removed, they are")
72+
{
73+
const exprt simplified=simplify_expr(
7074
typecast_exprt(
71-
symbol_exprt(
72-
"foo",
73-
java_boolean_type()),
74-
java_int_type()),
75-
java_boolean_type()),
76-
namespacet(symbol_tablet()));
77-
78-
REQUIRE(simplified.id()==ID_symbol);
79-
REQUIRE(simplified.type()==java_boolean_type());
80-
const auto &symbol=to_symbol_expr(simplified);
81-
REQUIRE(symbol.get_identifier()=="foo");
75+
typecast_exprt(symbol_exprt("foo", type), java_int_type()),
76+
type),
77+
namespacet(symbol_tablet()));
78+
79+
REQUIRE(simplified.id()==ID_symbol);
80+
REQUIRE(simplified.type()==type);
81+
const auto &symbol=to_symbol_expr(simplified);
82+
REQUIRE(symbol.get_identifier()=="foo");
83+
}
84+
85+
WHEN("Casts should remain, they are left untouched")
86+
{
87+
{
88+
const exprt simplified=simplify_expr(
89+
typecast_exprt(symbol_exprt("foo", type), java_int_type()),
90+
namespacet(symbol_tablet()));
91+
92+
REQUIRE(simplified.id()==ID_typecast);
93+
REQUIRE(simplified.type()==java_int_type());
94+
}
95+
96+
{
97+
const exprt simplified=simplify_expr(
98+
typecast_exprt(symbol_exprt("foo", java_int_type()), type),
99+
namespacet(symbol_tablet()));
100+
101+
REQUIRE(simplified.id()==ID_typecast);
102+
REQUIRE(simplified.type()==type);
103+
}
104+
}
105+
106+
WHEN("Deeply nested casts are present, they are collapsed appropriately")
107+
{
108+
{
109+
const exprt simplified=simplify_expr(
110+
typecast_exprt(
111+
typecast_exprt(
112+
typecast_exprt(
113+
typecast_exprt(
114+
typecast_exprt(symbol_exprt("foo", type), java_int_type()),
115+
type),
116+
java_int_type()),
117+
type),
118+
java_int_type()),
119+
namespacet(symbol_tablet()));
120+
121+
REQUIRE(
122+
simplified==typecast_exprt(symbol_exprt("foo", type), java_int_type()));
123+
}
124+
}
125+
}
126+
127+
} // namespace
128+
129+
TEST_CASE("Simplify Java boolean -> int -> boolean casts")
130+
{
131+
test_unnecessary_cast(java_boolean_type());
132+
}
133+
134+
TEST_CASE("Simplify Java byte -> int -> byte casts")
135+
{
136+
test_unnecessary_cast(java_byte_type());
137+
}
138+
139+
TEST_CASE("Simplify Java char -> int -> char casts")
140+
{
141+
test_unnecessary_cast(java_char_type());
142+
}
143+
144+
TEST_CASE("Simplify Java short -> int -> short casts")
145+
{
146+
test_unnecessary_cast(java_short_type());
82147
}

0 commit comments

Comments
 (0)