Skip to content

Commit 5009854

Browse files
committed
member_exprt now checks type of compound operand
This commit adds a precondition to the constructors of member_exprt that enforces that the compound operand has one of the compound types. A legacy constructor is offered to ease the transition.
1 parent e78eacf commit 5009854

File tree

9 files changed

+69
-22
lines changed

9 files changed

+69
-22
lines changed

jbmc/unit/java_bytecode/java_trace_validation/java_trace_validation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ TEST_CASE("java trace validation", "[core][java_trace_validation]")
2525
const symbol_exprt valid_symbol_expr = symbol_exprt("id", java_int_type());
2626
const symbol_exprt invalid_symbol_expr = symbol_exprt(java_int_type());
2727
const member_exprt valid_member =
28-
member_exprt(valid_symbol_expr, "member", java_int_type());
28+
member_exprt::unchecked(valid_symbol_expr, "member", java_int_type());
2929
const member_exprt invalid_member =
30-
member_exprt(plain_expr, "member", java_int_type());
30+
member_exprt::unchecked(plain_expr, "member", java_int_type());
3131
const constant_exprt invalid_constant = constant_exprt("", java_int_type());
3232
const constant_exprt valid_constant = constant_exprt("0", java_int_type());
3333
const index_exprt valid_index = index_exprt(

src/goto-programs/string_abstraction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,8 @@ bool string_abstractiont::build(const exprt &object, exprt &dest, bool write)
817817
if(object.id()==ID_member)
818818
{
819819
const member_exprt &o_mem=to_member_expr(object);
820-
dest=member_exprt(exprt(), o_mem.get_component_name(), abstract_type);
820+
dest = member_exprt::unchecked(
821+
exprt(), o_mem.get_component_name(), abstract_type);
821822
return build_wrap(
822823
o_mem.struct_op(), to_member_expr(dest).compound(), write);
823824
}

src/pointer-analysis/value_set.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1192,7 +1192,10 @@ void value_sett::get_reference_set_rec(
11921192

11931193
if(object.id()==ID_unknown)
11941194
insert(dest, exprt(ID_unknown, expr.type()));
1195-
else
1195+
else if(
1196+
object.type().id() == ID_struct ||
1197+
object.type().id() == ID_struct_tag || object.type().id() == ID_union ||
1198+
object.type().id() == ID_union_tag)
11961199
{
11971200
offsett o = it->second;
11981201

@@ -1218,6 +1221,8 @@ void value_sett::get_reference_set_rec(
12181221
else
12191222
insert(dest, exprt(ID_unknown, expr.type()));
12201223
}
1224+
else
1225+
insert(dest, exprt(ID_unknown, expr.type()));
12211226
}
12221227

12231228
return;

src/util/std_expr.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2780,15 +2780,44 @@ class member_exprt:public unary_exprt
27802780
member_exprt(exprt op, const irep_idt &component_name, typet _type)
27812781
: unary_exprt(ID_member, std::move(op), std::move(_type))
27822782
{
2783+
const auto &compound_type_id = compound().type().id();
2784+
PRECONDITION(
2785+
compound_type_id == ID_struct_tag || compound_type_id == ID_union_tag ||
2786+
compound_type_id == ID_struct || compound_type_id == ID_union);
27832787
set_component_name(component_name);
27842788
}
27852789

2790+
// legacy constructor without type checking,
2791+
// will be removed eventually
2792+
member_exprt(exprt op, const irep_idt &component_name, typet _type, int)
2793+
: unary_exprt(ID_member, std::move(op), std::move(_type))
2794+
{
2795+
set_component_name(component_name);
2796+
}
2797+
2798+
static member_exprt unchecked(exprt op, irep_idt component_name, typet type)
2799+
{
2800+
return member_exprt(
2801+
std::move(op), std::move(component_name), std::move(type), 0);
2802+
}
2803+
27862804
member_exprt(exprt op, const struct_typet::componentt &c)
27872805
: unary_exprt(ID_member, std::move(op), c.type())
27882806
{
2807+
const auto &compound_type_id = compound().type().id();
2808+
PRECONDITION(
2809+
compound_type_id == ID_struct_tag || compound_type_id == ID_union_tag ||
2810+
compound_type_id == ID_struct || compound_type_id == ID_union);
27892811
set_component_name(c.get_name());
27902812
}
27912813

2814+
// legacy constructor without type checking,
2815+
// will be removed eventually
2816+
static member_exprt unchecked(exprt op, struct_typet::componentt c)
2817+
{
2818+
return member_exprt(std::move(op), c.get_name(), c.type(), 0);
2819+
}
2820+
27922821
irep_idt get_component_name() const
27932822
{
27942823
return get(ID_component_name);

unit/analyses/variable-sensitivity/full_struct_abstract_object/merge.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ SCENARIO(
3434
auto val2 = std::map<std::string, int>{{"a", 1}, {"b", 4}, {"c", 5}};
3535

3636
// index_exprt for reading from an array
37-
const member_exprt a(nil_exprt(), "a", integer_typet());
38-
const member_exprt b(nil_exprt(), "b", integer_typet());
39-
const member_exprt c(nil_exprt(), "c", integer_typet());
37+
const auto a = member_exprt::unchecked(nil_exprt(), "a", integer_typet());
38+
const auto b = member_exprt::unchecked(nil_exprt(), "b", integer_typet());
39+
const auto c = member_exprt::unchecked(nil_exprt(), "c", integer_typet());
4040

4141
auto object_factory = variable_sensitivity_object_factoryt::configured_with(
4242
vsd_configt::constant_domain());

unit/analyses/variable-sensitivity/full_struct_abstract_object/struct_builder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ full_struct_abstract_objectt::constant_struct_pointert build_struct(
2626
environment,
2727
ns,
2828
std::stack<exprt>(),
29-
member_exprt(nil_exprt(), component.get_name(), component.type()),
29+
member_exprt::unchecked(
30+
nil_exprt(), component.get_name(), component.type()),
3031
environment.eval(op, ns),
3132
false);
3233

unit/goto-symex/expr_skeleton.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ SCENARIO("expr skeleton", "[core][goto-symex][symex-assign][expr-skeleton]")
2424
expr_skeletont::remove_op0(index_exprt{
2525
array_exprt{{}, array_typet{int_type, from_integer(2, size_type())}},
2626
from_integer(1, size_type())});
27-
const expr_skeletont member_skeleton = expr_skeletont::remove_op0(
28-
member_exprt{symbol_exprt{"struct1", typet{}}, "field1", int_type});
27+
const expr_skeletont member_skeleton =
28+
expr_skeletont::remove_op0(member_exprt::unchecked(
29+
symbol_exprt{"struct1", typet{}}, "field1", int_type));
2930
THEN(
3031
"Applying the skeletons to `foo` gives `foo`, `foo[index]` and "
3132
"`foo.field1` respectively")
@@ -35,7 +36,8 @@ SCENARIO("expr skeleton", "[core][goto-symex][symex-assign][expr-skeleton]")
3536
index_skeleton.apply(foo) ==
3637
index_exprt{foo, from_integer(1, size_type()), int_type});
3738
REQUIRE(
38-
member_skeleton.apply(foo) == member_exprt{foo, "field1", int_type});
39+
member_skeleton.apply(foo) ==
40+
member_exprt::unchecked(foo, "field1", int_type));
3941
}
4042
THEN(
4143
"The composition of `☐[index]` with `☐.field1` applied to `foo` gives "
@@ -45,9 +47,10 @@ SCENARIO("expr skeleton", "[core][goto-symex][symex-assign][expr-skeleton]")
4547
index_skeleton.compose(member_skeleton);
4648
REQUIRE(
4749
composition.apply(foo) ==
48-
index_exprt{member_exprt{foo, "field1", int_type},
49-
from_integer(1, size_type()),
50-
int_type});
50+
index_exprt{
51+
member_exprt::unchecked(foo, "field1", int_type),
52+
from_integer(1, size_type()),
53+
int_type});
5154
}
5255
THEN(
5356
"The composition of `☐[index]` with `☐` applied to `foo` gives "

unit/pointer-analysis/value_set.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ SCENARIO(
135135
WHEN("We query what (a1 WITH x = NULL).x points to")
136136
{
137137
with_exprt a1_with(
138-
a1_symbol.symbol_expr(), member_exprt(nil_exprt(), A_x), null_A_ptr);
138+
a1_symbol.symbol_expr(),
139+
member_exprt::unchecked(nil_exprt(), A_x),
140+
null_A_ptr);
139141

140142
member_exprt member_of_with(a1_with, A_x);
141143

@@ -153,7 +155,9 @@ SCENARIO(
153155
WHEN("We query what (a1 WITH x = NULL).y points to")
154156
{
155157
with_exprt a1_with(
156-
a1_symbol.symbol_expr(), member_exprt(nil_exprt(), A_x), null_A_ptr);
158+
a1_symbol.symbol_expr(),
159+
member_exprt::unchecked(nil_exprt(), A_x),
160+
null_A_ptr);
157161

158162
member_exprt member_of_with(a1_with, A_y);
159163

@@ -171,7 +175,9 @@ SCENARIO(
171175
WHEN("We query what (a1 WITH x = NULL) points to")
172176
{
173177
with_exprt a1_with(
174-
a1_symbol.symbol_expr(), member_exprt(nil_exprt(), A_x), null_A_ptr);
178+
a1_symbol.symbol_expr(),
179+
member_exprt::unchecked(nil_exprt(), A_x),
180+
null_A_ptr);
175181

176182
const std::vector<exprt> maybe_matching_with_result =
177183
value_set.get_value_set(a1_with, ns);

unit/solvers/smt2_incremental/object_tracking.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,18 @@ TEST_CASE("find_object_base_expression", "[core][smt2_incremental]")
2626
rowt{"Address of index", {index_exprt{object_base, index}, pointer_type}},
2727
rowt{
2828
"Address of struct member",
29-
{member_exprt{object_base, "baz", unsignedbv_typet{8}}, pointer_type}},
29+
{member_exprt::unchecked(object_base, "baz", unsignedbv_typet{8}),
30+
pointer_type}},
3031
rowt{
3132
"Address of index of struct member",
3233
{index_exprt{
33-
member_exprt{object_base, "baz", unsignedbv_typet{8}}, index},
34+
member_exprt::unchecked(object_base, "baz", unsignedbv_typet{8}),
35+
index},
3436
pointer_type}},
3537
rowt{
3638
"Address of struct member at index",
37-
{member_exprt{
38-
index_exprt{object_base, index}, "baz", unsignedbv_typet{8}},
39+
{member_exprt::unchecked(
40+
index_exprt{object_base, index}, "baz", unsignedbv_typet{8}),
3941
pointer_type}});
4042
SECTION(description)
4143
{
@@ -56,7 +58,7 @@ TEST_CASE("Tracking object base expressions", "[core][smt2_incremental]")
5658
address_of_exprt{index_exprt{foo, index}, pointer_type}, bar_address},
5759
notequal_exprt{
5860
address_of_exprt{
59-
member_exprt{foo, "baz", unsignedbv_typet{8}}, pointer_type},
61+
member_exprt::unchecked(foo, "baz", unsignedbv_typet{8}), pointer_type},
6062
bar_address}};
6163
SECTION("Find base expressions")
6264
{

0 commit comments

Comments
 (0)