Skip to content

Commit a5477ee

Browse files
committed
abstract_environment::merge returns object/modified pair
Eliminate boolean by-ref out parameter, instead returning a simple struct holding the merged object, and the modified flag.
1 parent ae36adc commit a5477ee

File tree

18 files changed

+358
-359
lines changed

18 files changed

+358
-359
lines changed

src/analyses/variable-sensitivity/abstract_aggregate_object.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,11 @@ class abstract_aggregate_objectt : public abstract_objectt,
135135

136136
for(auto &item : delta_view)
137137
{
138-
bool changes = false;
139-
abstract_object_pointert v_new =
140-
abstract_objectt::merge(item.m, item.get_other_map_value(), changes);
141-
if(changes)
138+
auto v_new = abstract_objectt::merge(item.m, item.get_other_map_value());
139+
if(v_new.modified)
142140
{
143141
modified = true;
144-
out_map.replace(item.k, v_new);
142+
out_map.replace(item.k, v_new.object);
145143
}
146144
}
147145

src/analyses/variable-sensitivity/abstract_environment.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,10 @@ bool abstract_environmentt::merge(
310310
env.map.get_delta_view(map, delta_view);
311311
for(const auto &entry : delta_view)
312312
{
313-
bool object_modified = false;
314-
abstract_object_pointert new_object = abstract_objectt::merge(
315-
entry.get_other_map_value(), entry.m, object_modified);
316-
modified |= object_modified;
317-
map.replace(entry.k, new_object);
313+
auto merge_result =
314+
abstract_objectt::merge(entry.get_other_map_value(), entry.m);
315+
modified |= merge_result.modified;
316+
map.replace(entry.k, merge_result.object);
318317
}
319318

320319
return modified;

src/analyses/variable-sensitivity/abstract_object.cpp

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -186,26 +186,15 @@ void abstract_objectt::output(
186186
}
187187
}
188188

189-
abstract_object_pointert abstract_objectt::merge(
190-
abstract_object_pointert op1,
191-
abstract_object_pointert op2,
192-
bool &out_modifications)
189+
abstract_objectt::merge_result abstract_objectt::merge(
190+
const abstract_object_pointert &op1,
191+
const abstract_object_pointert &op2)
193192
{
194193
abstract_object_pointert result = op1->should_use_base_merge(op2)
195194
? op1->abstract_object_merge(op2)
196195
: op1->merge(op2);
197196
// If no modifications, we will return the original pointer
198-
out_modifications = result != op1;
199-
200-
return result;
201-
}
202-
203-
abstract_object_pointert abstract_objectt::merge(
204-
abstract_object_pointert op1,
205-
abstract_object_pointert op2)
206-
{
207-
bool dummy;
208-
return merge(op1, op2, dummy);
197+
return {result, result != op1};
209198
}
210199

211200
bool abstract_objectt::should_use_base_merge(

src/analyses/variable-sensitivity/abstract_object.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,17 @@ class abstract_objectt : public std::enable_shared_from_this<abstract_objectt>
251251
/// \param op2: the second abstract object to merge
252252
/// \param out_modifications: reference to a flag indicating modification
253253
///
254-
/// \return The merged abstract object with the same sensitivity as the
255-
/// first parameter. out_modifications will be true if the resulting
256-
/// abstract object is different from op1
257-
static abstract_object_pointert merge(
258-
abstract_object_pointert op1,
259-
abstract_object_pointert op2,
260-
bool &out_modifications);
261-
static abstract_object_pointert
262-
merge(abstract_object_pointert op1, abstract_object_pointert op2);
254+
/// \return A pair containing the merged abstract object with the same
255+
/// sensitivity as op1, and a modified flag which
256+
/// will be true if the merged abstract object is different from op1
257+
struct merge_result
258+
{
259+
abstract_object_pointert object;
260+
bool modified;
261+
};
262+
static merge_result merge(
263+
const abstract_object_pointert &op1,
264+
const abstract_object_pointert &op2);
263265

264266
/// Interface method for the meet operation. Decides whether to use the base
265267
/// implementation or if a more precise abstraction is attainable.

src/analyses/variable-sensitivity/constant_pointer_abstract_object.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ abstract_object_pointert constant_pointer_abstract_objectt::write_dereference(
196196
{
197197
abstract_object_pointert pointed_value = environment.eval(value, ns);
198198
abstract_object_pointert merged_value =
199-
abstract_objectt::merge(pointed_value, new_value);
199+
abstract_objectt::merge(pointed_value, new_value).object;
200200
environment.assign(value, merged_value, ns);
201201
}
202202
else

src/analyses/variable-sensitivity/full_array_abstract_object.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ abstract_object_pointert apply_to_index_range(
3838
{
3939
auto at_index = fn(index_exprt(index_expr.array(), index));
4040

41-
result = (result == nullptr) ? at_index
42-
: abstract_objectt::merge(result, at_index);
41+
result = (result == nullptr)
42+
? at_index
43+
: abstract_objectt::merge(result, at_index).object;
4344

4445
if(result->is_top()) // no point in continuing once we've gone top
4546
break;
@@ -228,7 +229,7 @@ abstract_object_pointert full_array_abstract_objectt::read_element(
228229

229230
// Merge each known element into the TOP value
230231
for(const auto &element : map.get_view())
231-
result = abstract_objectt::merge(result, element.second);
232+
result = abstract_objectt::merge(result, element.second).object;
232233

233234
return result;
234235
}
@@ -341,7 +342,8 @@ abstract_object_pointert full_array_abstract_objectt::write_leaf_element(
341342
if(old_value.has_value()) // if not found it's top, so nothing to merge
342343
{
343344
result->map.replace(
344-
index_value, abstract_objectt::merge(old_value.value(), value));
345+
index_value,
346+
abstract_objectt::merge(old_value.value(), value).object);
345347
}
346348

347349
DATA_INVARIANT(result->verify(), "Structural invariants maintained");

src/analyses/variable-sensitivity/full_struct_abstract_object.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ abstract_object_pointert full_struct_abstract_objectt::write_component(
176176
return result;
177177
}
178178

179-
result->map.replace(c, abstract_objectt::merge(old_value.value(), value));
179+
result->map.replace(
180+
c, abstract_objectt::merge(old_value.value(), value).object);
180181
}
181182
else
182183
{

src/analyses/variable-sensitivity/value_set_abstract_value.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,12 @@ static void merge_all_possible_results(
142142
if(expr_with_evaluated_operands_filled_in.is_constant())
143143
{
144144
auto post_merge = abstract_objectt::merge(
145-
out_value,
146-
std::make_shared<value_set_abstract_valuet>(
147-
expr.type(),
148-
value_set_abstract_valuet::valuest{
149-
expr_with_evaluated_operands_filled_in}));
145+
out_value,
146+
std::make_shared<value_set_abstract_valuet>(
147+
expr.type(),
148+
value_set_abstract_valuet::valuest{
149+
expr_with_evaluated_operands_filled_in}))
150+
.object;
150151
if(
151152
auto post_merge_casted =
152153
std::dynamic_pointer_cast<const value_set_abstract_valuet>(

src/analyses/variable-sensitivity/write_location_context.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,24 +117,22 @@ write_location_contextt::merge(abstract_object_pointert other) const
117117

118118
if(cast_other)
119119
{
120-
bool child_modified = false;
121-
122120
auto merged_child = abstract_objectt::merge(
123-
child_abstract_object, cast_other->child_abstract_object, child_modified);
121+
child_abstract_object, cast_other->child_abstract_object);
124122

125123
abstract_objectt::locationst location_union =
126124
get_location_union(cast_other->get_last_written_locations());
127125
// If the union is larger than the initial set, then update.
128126
bool merge_locations =
129127
location_union.size() > get_last_written_locations().size();
130128

131-
if(child_modified || merge_locations)
129+
if(merged_child.modified || merge_locations)
132130
{
133131
const auto &result =
134132
std::dynamic_pointer_cast<write_location_contextt>(mutable_clone());
135-
if(child_modified)
133+
if(merged_child.modified)
136134
{
137-
result->set_child(merged_child);
135+
result->set_child(merged_child.object);
138136
}
139137
if(merge_locations)
140138
{

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

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@ SCENARIO(
2525
abstract_object_pointert op1 = make_top_object();
2626
abstract_object_pointert op2 = make_top_object();
2727

28-
bool modified;
29-
auto result = abstract_objectt::merge(op1, op2, modified);
28+
auto result = abstract_objectt::merge(op1, op2);
3029

3130
THEN("result is unmodified TOP")
3231
{
33-
EXPECT_UNMODIFIED(result, modified);
32+
EXPECT_UNMODIFIED(result);
3433
EXPECT_TOP(result);
3534
}
3635
}
@@ -39,12 +38,11 @@ SCENARIO(
3938
abstract_object_pointert op1 = make_top_object();
4039
abstract_object_pointert op2 = make_bottom_object();
4140

42-
bool modified;
43-
auto result = abstract_objectt::merge(op1, op2, modified);
41+
auto result = abstract_objectt::merge(op1, op2);
4442

4543
THEN("result is unmodified TOP")
4644
{
47-
EXPECT_UNMODIFIED(result, modified);
45+
EXPECT_UNMODIFIED(result);
4846
EXPECT_TOP(result);
4947
}
5048
}
@@ -53,12 +51,11 @@ SCENARIO(
5351
abstract_object_pointert op1 = make_bottom_object();
5452
abstract_object_pointert op2 = make_top_object();
5553

56-
bool modified;
57-
auto result = abstract_objectt::merge(op1, op2, modified);
54+
auto result = abstract_objectt::merge(op1, op2);
5855

5956
THEN("result is modified TOP")
6057
{
61-
EXPECT_MODIFIED(result, modified);
58+
EXPECT_MODIFIED(result);
6259
EXPECT_TOP(result);
6360
}
6461
}
@@ -67,12 +64,11 @@ SCENARIO(
6764
abstract_object_pointert op1 = make_bottom_object();
6865
abstract_object_pointert op2 = make_bottom_object();
6966

70-
bool modified;
71-
auto result = abstract_objectt::merge(op1, op2, modified);
67+
auto result = abstract_objectt::merge(op1, op2);
7268

7369
THEN("result is unmodified BOTTOM")
7470
{
75-
EXPECT_UNMODIFIED(result, modified);
71+
EXPECT_UNMODIFIED(result);
7672
EXPECT_BOTTOM(result);
7773
}
7874
}
@@ -99,12 +95,11 @@ SCENARIO(
9995
auto top1 = make_top_object();
10096
auto op2 = make_constant(val1, environment, ns);
10197

102-
bool modified;
103-
auto result = abstract_objectt::merge(top1, op2, modified);
98+
auto result = abstract_objectt::merge(top1, op2);
10499

105100
THEN("the result is unmodified TOP")
106101
{
107-
EXPECT_UNMODIFIED(result, modified);
102+
EXPECT_UNMODIFIED(result);
108103
EXPECT_TOP(result);
109104
}
110105
}
@@ -113,12 +108,11 @@ SCENARIO(
113108
auto top1 = make_top_object();
114109
auto top2 = make_top_constant();
115110

116-
bool modified;
117-
auto result = abstract_objectt::merge(top1, top2, modified);
111+
auto result = abstract_objectt::merge(top1, top2);
118112

119113
THEN("the result is unmodified TOP")
120114
{
121-
EXPECT_UNMODIFIED(result, modified);
115+
EXPECT_UNMODIFIED(result);
122116
EXPECT_TOP(result);
123117
}
124118
}
@@ -127,12 +121,11 @@ SCENARIO(
127121
auto top1 = make_top_object();
128122
auto bottom2 = make_bottom_constant();
129123

130-
bool modified;
131-
auto result = abstract_objectt::merge(top1, bottom2, modified);
124+
auto result = abstract_objectt::merge(top1, bottom2);
132125

133126
THEN("the result is unmodified TOP")
134127
{
135-
EXPECT_UNMODIFIED(result, modified);
128+
EXPECT_UNMODIFIED(result);
136129
EXPECT_TOP(result);
137130
}
138131
}
@@ -141,12 +134,11 @@ SCENARIO(
141134
auto op1 = make_bottom_object();
142135
auto op2 = make_constant(val1, environment, ns);
143136

144-
bool modified;
145-
auto result = abstract_objectt::merge(op1, op2, modified);
137+
auto result = abstract_objectt::merge(op1, op2);
146138

147139
THEN("the result is modified TOP")
148140
{
149-
EXPECT_MODIFIED(result, modified);
141+
EXPECT_MODIFIED(result);
150142
EXPECT_TOP(result);
151143
}
152144
}
@@ -155,12 +147,11 @@ SCENARIO(
155147
auto op1 = make_bottom_object();
156148
auto top2 = make_top_constant();
157149

158-
bool modified;
159-
auto result = abstract_objectt::merge(op1, top2, modified);
150+
auto result = abstract_objectt::merge(op1, top2);
160151

161152
THEN("the result is modified TOP")
162153
{
163-
EXPECT_MODIFIED(result, modified);
154+
EXPECT_MODIFIED(result);
164155
EXPECT_TOP(result);
165156
}
166157
}
@@ -169,12 +160,11 @@ SCENARIO(
169160
auto bottom1 = make_bottom_object();
170161
auto bottom2 = make_bottom_constant();
171162

172-
bool modified;
173-
auto result = abstract_objectt::merge(bottom1, bottom2, modified);
163+
auto result = abstract_objectt::merge(bottom1, bottom2);
174164

175165
THEN("result is unmodified BOTTOM")
176166
{
177-
EXPECT_UNMODIFIED(result, modified);
167+
EXPECT_UNMODIFIED(result);
178168
EXPECT_BOTTOM(result);
179169
}
180170
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
static merge_result<const constant_abstract_valuet>
1616
merge(abstract_object_pointert op1, abstract_object_pointert op2)
1717
{
18-
bool modified;
19-
auto result = abstract_objectt::merge(op1, op2, modified);
18+
auto result = abstract_objectt::merge(op1, op2);
2019

21-
return {modified, as_constant(result)};
20+
return {result.modified, as_constant(result.object)};
2221
}
2322

2423
SCENARIO(

0 commit comments

Comments
 (0)