@@ -42,21 +42,15 @@ abstract_object_pointert liveness_contextt::write(
42
42
const abstract_object_pointert &value,
43
43
bool merging_write) const
44
44
{
45
- abstract_object_pointert updated_child = child_abstract_object->write (
46
- environment, ns, stack, specifier, value, merging_write);
47
-
48
- // Only perform an update if the write to the child has in fact changed it...
49
- if (updated_child == child_abstract_object)
45
+ auto updated = std::dynamic_pointer_cast<const liveness_contextt>(
46
+ write_location_contextt::write (
47
+ environment, ns, stack, specifier, value, merging_write));
48
+ if (updated == shared_from_this ())
50
49
return shared_from_this ();
51
50
52
- // Need to ensure the result of the write is still wrapped in a dependency
53
- // context
54
- const auto &result =
55
- std::dynamic_pointer_cast<liveness_contextt>(mutable_clone ());
56
-
57
- result->set_child (updated_child);
58
-
59
- // Update the child and record the updated write locations
51
+ // record the updated write locations
52
+ auto result =
53
+ std::dynamic_pointer_cast<liveness_contextt>(updated->mutable_clone ());
60
54
auto value_context =
61
55
std::dynamic_pointer_cast<const liveness_contextt>(value);
62
56
if (value_context)
@@ -83,91 +77,40 @@ abstract_object_pointert liveness_contextt::merge(
83
77
84
78
if (cast_other)
85
79
{
86
- auto merge_fn = [&widen_mode](
87
- const abstract_object_pointert &op1,
88
- const abstract_object_pointert &op2) {
89
- return abstract_objectt::merge (op1, op2, widen_mode);
90
- };
91
- return combine (cast_other, merge_fn);
80
+ auto merged = std::dynamic_pointer_cast<const liveness_contextt>(
81
+ write_location_contextt::merge (other, widen_mode));
82
+ return reset_location_on_merge (merged);
92
83
}
93
84
94
85
return abstract_objectt::merge (other, widen_mode);
95
86
}
96
87
97
- // need wrapper function here to disambiguate meet overload
98
- abstract_objectt::combine_result object_meet (
99
- const abstract_object_pointert &op1,
100
- const abstract_object_pointert &op2)
101
- {
102
- return abstract_objectt::meet (op1, op2);
103
- }
104
-
105
- abstract_object_pointert
106
- liveness_contextt::meet (const abstract_object_pointert &other) const
107
- {
108
- auto cast_other = std::dynamic_pointer_cast<const liveness_contextt>(other);
109
-
110
- if (cast_other)
111
- return combine (cast_other, object_meet);
112
-
113
- return abstract_objectt::meet (other);
114
- }
115
-
116
- bool liveness_contextt::at_same_location (const liveness_context_ptrt &rhs) const
117
- {
118
- return has_location () && rhs->has_location () &&
119
- (get_location ()->location_number ==
120
- rhs->get_location ()->location_number );
121
- }
122
-
123
- abstract_object_pointert liveness_contextt::combine (
124
- const liveness_context_ptrt &other,
125
- combine_fn fn) const
126
- {
127
- auto combined_child = fn (child_abstract_object, other->child_abstract_object );
128
- auto location_match = at_same_location (other);
129
-
130
- if (combined_child.modified || !location_match)
131
- {
132
- const auto &result =
133
- std::dynamic_pointer_cast<liveness_contextt>(mutable_clone ());
134
- result->set_child (combined_child.object );
135
- result->reset_location ();
136
- return result;
137
- }
138
-
139
- return shared_from_this ();
140
- }
141
-
142
88
abstract_object_pointert liveness_contextt::abstract_object_merge_internal (
143
89
const abstract_object_pointert &other) const
144
90
{
145
- auto other_context =
146
- std::dynamic_pointer_cast<const liveness_contextt>(other);
147
-
148
- if (!other_context)
149
- return shared_from_this ();
150
-
151
- if (other_context && !at_same_location (other_context))
152
- {
153
- auto result = std::dynamic_pointer_cast<liveness_contextt>(mutable_clone ());
154
- result->reset_location ();
155
- return result;
156
- }
157
-
158
- return shared_from_this ();
91
+ auto merged = std::dynamic_pointer_cast<const liveness_contextt>(
92
+ write_location_contextt::abstract_object_merge_internal (other));
93
+ return reset_location_on_merge (merged);
159
94
}
160
95
161
- void liveness_contextt::reset_location ()
96
+ abstract_object_pointert liveness_contextt::reset_location_on_merge (
97
+ const liveness_context_ptrt &merged) const
162
98
{
163
- assign_location.reset ();
99
+ if (merged == shared_from_this ())
100
+ return shared_from_this ();
101
+
102
+ auto updated =
103
+ std::dynamic_pointer_cast<liveness_contextt>(merged->mutable_clone ());
104
+ updated->assign_location .reset ();
105
+ return updated;
164
106
}
165
107
166
108
context_abstract_objectt::context_abstract_object_ptrt
167
109
liveness_contextt::update_location_context_internal (
168
110
const locationst &locations) const
169
111
{
170
112
auto result = std::dynamic_pointer_cast<liveness_contextt>(mutable_clone ());
113
+ result->set_last_written_locations (locations);
171
114
result->set_location (*locations.cbegin ());
172
115
return result;
173
116
}
@@ -198,44 +141,6 @@ void liveness_contextt::output(
198
141
out << " @ [undefined]" ;
199
142
}
200
143
201
- /* *
202
- * Determine whether 'this' abstract_object has been modified in comparison
203
- * to a previous 'before' state.
204
- *
205
- * \param before the abstract_object_pointert to use as a reference to
206
- * compare against
207
- *
208
- * \return true if 'this' is considered to have been modified in comparison
209
- * to 'before', false otherwise.
210
- */
211
- bool liveness_contextt::has_been_modified (
212
- const abstract_object_pointert &before) const
213
- {
214
- if (this == before.get ())
215
- return false ;
216
-
217
- auto before_context =
218
- std::dynamic_pointer_cast<const liveness_contextt>(before);
219
-
220
- if (!before_context)
221
- {
222
- // The other context is not something we understand, so must assume
223
- // that the abstract_object has been modified
224
- return true ;
225
- }
226
-
227
- // Even if the pointers are different, it maybe that it has changed only
228
- // because of a merge operation, rather than an actual write. Given that
229
- // this class has knowledge of where writes have occured, use that
230
- // information to determine if any writes have happened and use that as the
231
- // proxy for whether the value has changed or not.
232
- //
233
- // For two sets of last written locations to match,
234
- // each location in one set must be equal to precisely one location
235
- // in the other, since a set can assume at most one match
236
- return !at_same_location (before_context);
237
- }
238
-
239
144
abstract_object_pointert
240
145
liveness_contextt::merge_location_context (const locationt &location) const
241
146
{
0 commit comments