Skip to content

Commit 633790b

Browse files
authored
Merge pull request #6710 from tautschnig/bugfixes/array-ops-dependence-graph
Handle array_{copy,replace,set} in dependence graph
2 parents f34b180 + 5e83d5b commit 633790b

File tree

4 files changed

+86
-7
lines changed

4 files changed

+86
-7
lines changed

regression/cbmc/Bool5/full-slice.desc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
--full-slice
4+
Generated 4 VCC\(s\), 0 remaining after simplification
5+
^VERIFICATION SUCCESSFUL$
6+
^EXIT=0$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring

src/analyses/goto_rw.cpp

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,17 @@ void rw_range_sett::get_objects_rec(const typet &type)
621621
}
622622
}
623623

624+
void rw_range_sett::get_array_objects(
625+
const irep_idt &,
626+
goto_programt::const_targett,
627+
get_modet mode,
628+
const exprt &pointer)
629+
{
630+
object_descriptor_exprt ode;
631+
ode.build(dereference_exprt{skip_typecast(pointer)}, ns);
632+
get_objects_rec(mode, ode.root_object(), -1, -1);
633+
}
634+
624635
void rw_range_set_value_sett::get_objects_dereference(
625636
get_modet mode,
626637
const dereference_exprt &deref,
@@ -737,6 +748,50 @@ static void goto_rw_assign(
737748
rw_set.get_objects_rec(function, target, rw_range_sett::get_modet::READ, rhs);
738749
}
739750

751+
static void goto_rw_other(
752+
const irep_idt &function,
753+
goto_programt::const_targett target,
754+
const codet &code,
755+
rw_range_sett &rw_set)
756+
{
757+
const irep_idt &statement = code.get_statement();
758+
759+
if(statement == ID_printf)
760+
{
761+
// if it's printf, mark the operands as read here
762+
for(const auto &op : code.operands())
763+
{
764+
rw_set.get_objects_rec(
765+
function, target, rw_range_sett::get_modet::READ, op);
766+
}
767+
}
768+
else if(statement == ID_array_equal)
769+
{
770+
// mark the dereferenced operands as being read
771+
for(const auto &op : code.operands())
772+
{
773+
rw_set.get_array_objects(
774+
function, target, rw_range_sett::get_modet::READ, op);
775+
}
776+
}
777+
else if(statement == ID_array_set)
778+
{
779+
PRECONDITION(code.operands().size() == 2);
780+
rw_set.get_array_objects(
781+
function, target, rw_range_sett::get_modet::LHS_W, code.op0());
782+
rw_set.get_objects_rec(
783+
function, target, rw_range_sett::get_modet::READ, code.op1());
784+
}
785+
else if(statement == ID_array_copy || statement == ID_array_replace)
786+
{
787+
PRECONDITION(code.operands().size() == 2);
788+
rw_set.get_array_objects(
789+
function, target, rw_range_sett::get_modet::LHS_W, code.op0());
790+
rw_set.get_array_objects(
791+
function, target, rw_range_sett::get_modet::READ, code.op1());
792+
}
793+
}
794+
740795
static void goto_rw(
741796
const irep_idt &function,
742797
goto_programt::const_targett target,
@@ -787,13 +842,7 @@ void goto_rw(
787842
break;
788843

789844
case OTHER:
790-
// if it's printf, mark the operands as read here
791-
if(target->get_other().get_statement() == ID_printf)
792-
{
793-
for(const auto &op : target->get_other().operands())
794-
rw_set.get_objects_rec(
795-
function, target, rw_range_sett::get_modet::READ, op);
796-
}
845+
goto_rw_other(function, target, target->get_other(), rw_set);
797846
break;
798847

799848
case SKIP:

src/analyses/goto_rw.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,12 @@ class rw_range_sett
148148
get_objects_rec(type);
149149
}
150150

151+
virtual void get_array_objects(
152+
const irep_idt &,
153+
goto_programt::const_targett,
154+
get_modet,
155+
const exprt &);
156+
151157
void output(std::ostream &out) const;
152158

153159
protected:
@@ -288,6 +294,18 @@ class rw_range_set_value_sett:public rw_range_sett
288294
rw_range_sett::get_objects_rec(type);
289295
}
290296

297+
void get_array_objects(
298+
const irep_idt &_function,
299+
goto_programt::const_targett _target,
300+
get_modet mode,
301+
const exprt &pointer) override
302+
{
303+
function = _function;
304+
target = _target;
305+
306+
rw_range_sett::get_array_objects(_function, _target, mode, pointer);
307+
}
308+
291309
protected:
292310
value_setst &value_sets;
293311
irep_idt function;

src/analyses/reaching_definitions.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ void rd_range_domaint::transform(
126126
// initial (non-deterministic) value
127127
else if(from->is_decl())
128128
transform_assign(ns, from, function_from, from, *rd);
129+
// array_set, array_copy, array_replace have side effects
130+
else if(from->is_other())
131+
transform_assign(ns, from, function_from, from, *rd);
129132
}
130133

131134
/// Computes an instance obtained from a `*this` by transformation over `DEAD v`

0 commit comments

Comments
 (0)