@@ -23,7 +23,6 @@ assigns_clauset::targett::targett(
2323 const assigns_clauset &parent,
2424 const exprt &expr)
2525 : address(address_of_exprt(normalize(expr))),
26- expr(expr),
2726 id(expr.id()),
2827 parent(parent)
2928{
@@ -89,17 +88,18 @@ assigns_clauset::assigns_clauset(
8988 const exprt &expr,
9089 const messaget &log,
9190 const namespacet &ns)
92- : expr (expr), log(log), ns(ns)
91+ : location (expr.source_location() ), log(log), ns(ns)
9392{
9493 for (const auto &target_expr : expr.operands ())
9594 {
96- add_target (target_expr);
95+ add_to_global_write_set (target_expr);
9796 }
9897}
9998
100- void assigns_clauset::add_target (const exprt &target_expr)
99+ void assigns_clauset::add_to_global_write_set (const exprt &target_expr)
101100{
102- auto insertion_succeeded = targets.emplace (*this , target_expr).second ;
101+ auto insertion_succeeded =
102+ global_write_set.emplace (*this , target_expr).second ;
103103
104104 if (!insertion_succeeded)
105105 {
@@ -110,32 +110,50 @@ void assigns_clauset::add_target(const exprt &target_expr)
110110 }
111111}
112112
113- void assigns_clauset::remove_target (const exprt &target_expr)
113+ void assigns_clauset::remove_from_global_write_set (const exprt &target_expr)
114114{
115- targets.erase (targett (*this , targett::normalize (target_expr)));
115+ global_write_set.erase (targett (*this , target_expr));
116+ }
117+
118+ void assigns_clauset::add_to_local_write_set (const exprt &expr)
119+ {
120+ local_write_set.emplace (*this , expr);
121+ }
122+
123+ void assigns_clauset::remove_from_local_write_set (const exprt &expr)
124+ {
125+ local_write_set.erase (targett (*this , expr));
116126}
117127
118128goto_programt assigns_clauset::generate_havoc_code () const
119129{
120130 modifiest modifies;
121- for (const auto &target : targets)
131+ for (const auto &target : global_write_set)
132+ modifies.insert (target.address .object ());
133+
134+ for (const auto &target : local_write_set)
122135 modifies.insert (target.address .object ());
123136
124137 goto_programt havoc_statements;
125- append_havoc_code (expr. source_location () , modifies, havoc_statements);
138+ append_havoc_code (location , modifies, havoc_statements);
126139 return havoc_statements;
127140}
128141
129142exprt assigns_clauset::generate_containment_check (const exprt &lhs) const
130143{
131144 // If write set is empty, no assignment is allowed.
132- if (targets .empty ())
145+ if (global_write_set. empty () && local_write_set .empty ())
133146 return false_exprt ();
134147
135148 const auto lhs_address = address_of_exprt (targett::normalize (lhs));
136149
137150 exprt::operandst condition;
138- for (const auto &target : targets)
151+ for (const auto &target : local_write_set)
152+ {
153+ condition.push_back (target.generate_containment_check (lhs_address));
154+ }
155+
156+ for (const auto &target : global_write_set)
139157 {
140158 condition.push_back (target.generate_containment_check (lhs_address));
141159 }
@@ -145,11 +163,16 @@ exprt assigns_clauset::generate_containment_check(const exprt &lhs) const
145163exprt assigns_clauset::generate_subset_check (
146164 const assigns_clauset &subassigns) const
147165{
148- if (subassigns.targets .empty ())
166+ if (subassigns.global_write_set .empty ())
149167 return true_exprt ();
150168
169+ INVARIANT (
170+ subassigns.local_write_set .empty (),
171+ " Local write set for function calls should be empty at this point.\n " +
172+ subassigns.location .as_string ());
173+
151174 exprt result = true_exprt ();
152- for (const auto &subtarget : subassigns.targets )
175+ for (const auto &subtarget : subassigns.global_write_set )
153176 {
154177 // TODO: Optimize the implication generated due to the validity check.
155178 // In some cases, e.g. when `subtarget` is known to be `NULL`,
@@ -158,7 +181,12 @@ exprt assigns_clauset::generate_subset_check(
158181 w_ok_exprt (subtarget.address , from_integer (0 , unsigned_int_type ()));
159182
160183 exprt::operandst current_subtarget_found_conditions;
161- for (const auto &target : targets)
184+ for (const auto &target : global_write_set)
185+ {
186+ current_subtarget_found_conditions.push_back (
187+ target.generate_containment_check (subtarget.address ));
188+ }
189+ for (const auto &target : local_write_set)
162190 {
163191 current_subtarget_found_conditions.push_back (
164192 target.generate_containment_check (subtarget.address ));
0 commit comments