Skip to content

Commit b44201c

Browse files
committed
Constant propagation: Support non-symbol left-hand sides, soundness
1. Properly handle index, member, or dereference expressions on the left-hand side of assignments. 2. If we find something on the left-hand side that we don't support (maybe byte extracts, if-expressions, type casts, or maybe something else), set the entire value set to top to ensure soundness.
1 parent 3f64f03 commit b44201c

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

regression/goto-analyzer/constant_propagation_09/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--constants --verify
44
^EXIT=0$

regression/goto-analyzer/constant_propagation_11/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--constants --verify
44
^EXIT=0$

regression/goto-analyzer/constant_propagation_14/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
--constants --verify
44
^EXIT=0$

src/analyses/constant_propagator.cpp

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,50 @@ void constant_propagator_domaint::assign_rec(
3636
const namespacet &ns,
3737
const constant_propagator_ait *cp)
3838
{
39-
if(lhs.id()!=ID_symbol)
40-
return;
39+
if(lhs.id() == ID_dereference)
40+
{
41+
const bool have_dirty = (cp != nullptr);
4142

42-
if(cp && !cp->should_track_value(lhs, ns))
43-
return;
43+
if(have_dirty)
44+
dest_values.set_dirty_to_top(cp->dirty, ns);
45+
else
46+
dest_values.set_to_top();
47+
}
48+
else if(lhs.id() == ID_index)
49+
{
50+
const index_exprt &index_expr = to_index_expr(lhs);
51+
with_exprt new_rhs(index_expr.array(), index_expr.index(), rhs);
52+
assign_rec(dest_values, index_expr.array(), new_rhs, ns, cp);
53+
}
54+
else if(lhs.id() == ID_member)
55+
{
56+
const member_exprt &member_expr = to_member_expr(lhs);
57+
with_exprt new_rhs(member_expr.compound(), exprt(ID_member_name), rhs);
58+
new_rhs.where().set(ID_component_name, member_expr.get_component_name());
59+
assign_rec(dest_values, member_expr.compound(), new_rhs, ns, cp);
60+
}
61+
else if(lhs.id() == ID_symbol)
62+
{
63+
if(cp && !cp->should_track_value(lhs, ns))
64+
return;
4465

45-
const symbol_exprt &s=to_symbol_expr(lhs);
66+
const symbol_exprt &s = to_symbol_expr(lhs);
4667

47-
exprt tmp=rhs;
48-
partial_evaluate(dest_values, tmp, ns);
68+
exprt tmp = rhs;
69+
partial_evaluate(dest_values, tmp, ns);
4970

50-
if(dest_values.is_constant(tmp))
51-
{
52-
DATA_INVARIANT(
53-
base_type_eq(ns.lookup(s).type, tmp.type(), ns),
54-
"type of constant to be replaced should match");
55-
dest_values.set_to(s, tmp);
71+
if(dest_values.is_constant(tmp))
72+
{
73+
DATA_INVARIANT(
74+
base_type_eq(ns.lookup(s).type, tmp.type(), ns),
75+
"type of constant to be replaced should match");
76+
dest_values.set_to(s, tmp);
77+
}
78+
else
79+
dest_values.set_to_top(s);
5680
}
5781
else
58-
dest_values.set_to_top(s);
82+
dest_values.set_to_top();
5983
}
6084

6185
void constant_propagator_domaint::transform(

0 commit comments

Comments
 (0)