Skip to content

Commit d18bd36

Browse files
committed
Pass widen_mode down into abstract_object::merge
1 parent 15cfc1c commit d18bd36

31 files changed

+254
-249
lines changed

src/analyses/variable-sensitivity/abstract_aggregate_object.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ class abstract_aggregate_objectt : public abstract_objectt,
125125
static bool merge_shared_maps(
126126
const sharing_mapt<keyt, abstract_object_pointert, false, hash> &map1,
127127
const sharing_mapt<keyt, abstract_object_pointert, false, hash> &map2,
128-
sharing_mapt<keyt, abstract_object_pointert, false, hash> &out_map)
128+
sharing_mapt<keyt, abstract_object_pointert, false, hash> &out_map,
129+
const wident &widen_mode)
129130
{
130131
bool modified = false;
131132

@@ -135,7 +136,8 @@ class abstract_aggregate_objectt : public abstract_objectt,
135136

136137
for(auto &item : delta_view)
137138
{
138-
auto v_new = abstract_objectt::merge(item.m, item.get_other_map_value());
139+
auto v_new =
140+
abstract_objectt::merge(item.m, item.get_other_map_value(), widen_mode);
139141
if(v_new.modified)
140142
{
141143
modified = true;

src/analyses/variable-sensitivity/abstract_environment.cpp

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -335,33 +335,27 @@ bool abstract_environmentt::merge(
335335
{
336336
// for each entry in the incoming environment we need to either add it
337337
// if it is new, or merge with the existing key if it is not present
338-
339338
if(bottom)
340339
{
341340
*this = env;
342341
return !env.bottom;
343342
}
344-
else if(env.bottom)
345-
{
343+
344+
if(env.bottom)
346345
return false;
347-
}
348-
else
349-
{
350-
// For each element in the intersection of map and env.map merge
351-
// If the result of the merge is top, remove from the map
352-
bool modified = false;
353-
decltype(env.map)::delta_viewt delta_view;
354-
env.map.get_delta_view(map, delta_view);
355-
for(const auto &entry : delta_view)
356-
{
357-
auto merge_result =
358-
abstract_objectt::merge(entry.get_other_map_value(), entry.m);
359-
modified |= merge_result.modified;
360-
map.replace(entry.k, merge_result.object);
361-
}
362346

363-
return modified;
347+
// For each element in the intersection of map and env.map merge
348+
// If the result of the merge is top, remove from the map
349+
bool modified = false;
350+
for(const auto &entry : env.map.get_delta_view(map))
351+
{
352+
auto merge_result =
353+
abstract_objectt::merge(entry.get_other_map_value(), entry.m, widen_mode);
354+
modified |= merge_result.modified;
355+
map.replace(entry.k, merge_result.object);
364356
}
357+
358+
return modified;
365359
}
366360

367361
void abstract_environmentt::havoc(const std::string &havoc_string)

src/analyses/variable-sensitivity/abstract_object.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ const typet &abstract_objectt::type() const
5555
return t;
5656
}
5757

58-
abstract_object_pointert
59-
abstract_objectt::merge(const abstract_object_pointert &other) const
58+
abstract_object_pointert abstract_objectt::merge(
59+
const abstract_object_pointert &other,
60+
const wident &widen_mode) const
6061
{
6162
return abstract_object_merge(other);
6263
}
@@ -191,11 +192,12 @@ void abstract_objectt::output(
191192

192193
abstract_objectt::merge_result abstract_objectt::merge(
193194
const abstract_object_pointert &op1,
194-
const abstract_object_pointert &op2)
195+
const abstract_object_pointert &op2,
196+
const wident &widen_mode)
195197
{
196198
abstract_object_pointert result = op1->should_use_base_merge(op2)
197199
? op1->abstract_object_merge(op2)
198-
: op1->merge(op2);
200+
: op1->merge(op2, widen_mode);
199201
// If no modifications, we will return the original pointer
200202
return {result, result != op1};
201203
}

src/analyses/variable-sensitivity/abstract_object.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class typet;
4343
class constant_exprt;
4444
class abstract_environmentt;
4545
class namespacet;
46+
enum class wident;
4647

4748
#define CLONE \
4849
internal_abstract_object_pointert mutable_clone() const override \
@@ -261,7 +262,8 @@ class abstract_objectt : public std::enable_shared_from_this<abstract_objectt>
261262
};
262263
static merge_result merge(
263264
const abstract_object_pointert &op1,
264-
const abstract_object_pointert &op2);
265+
const abstract_object_pointert &op2,
266+
const wident &widen_mode);
265267

266268
/// Interface method for the meet operation. Decides whether to use the base
267269
/// implementation or if a more precise abstraction is attainable.
@@ -430,10 +432,11 @@ class abstract_objectt : public std::enable_shared_from_this<abstract_objectt>
430432
/// the object would be unchanged, then would return itself.
431433
///
432434
/// \param other: The object to merge with this
435+
/// \param widen_mode: Indicates if this is a widening merge
433436
///
434437
/// \return Returns the result of the merge.
435438
virtual abstract_object_pointert
436-
merge(const abstract_object_pointert &other) const;
439+
merge(const abstract_object_pointert &other, const wident &widen_mode) const;
437440

438441
/// Helper function for base meet. Two cases: return itself (if trivially
439442
/// contained in other); return BOTTOM otherwise.

src/analyses/variable-sensitivity/constant_abstract_value.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,19 +111,21 @@ void constant_abstract_valuet::output(
111111
}
112112
}
113113

114-
abstract_object_pointert
115-
constant_abstract_valuet::merge(const abstract_object_pointert &other) const
114+
abstract_object_pointert constant_abstract_valuet::merge(
115+
const abstract_object_pointert &other,
116+
const wident &widen_mode) const
116117
{
117118
auto cast_other =
118119
std::dynamic_pointer_cast<const abstract_value_objectt>(other);
119120
if(cast_other)
120-
return merge_with_value(cast_other);
121+
return merge_with_value(cast_other, widen_mode);
121122

122-
return abstract_objectt::merge(other);
123+
return abstract_objectt::merge(other, widen_mode);
123124
}
124125

125126
abstract_object_pointert constant_abstract_valuet::merge_with_value(
126-
const abstract_value_pointert &other) const
127+
const abstract_value_pointert &other,
128+
const wident &widen_mode) const
127129
{
128130
auto other_expr = other->to_constant();
129131
if(is_bottom() && other_expr.is_constant())
@@ -132,7 +134,7 @@ abstract_object_pointert constant_abstract_valuet::merge_with_value(
132134
if(value == other_expr) // Can we actually merge these value
133135
return shared_from_this();
134136

135-
return abstract_objectt::merge(other);
137+
return abstract_objectt::merge(other, widen_mode);
136138
}
137139

138140
abstract_object_pointert

src/analyses/variable-sensitivity/constant_abstract_value.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,23 +68,27 @@ class constant_abstract_valuet : public abstract_value_objectt
6868
/// otherwise falls back to the parent merge
6969
///
7070
/// \param other: the abstract object to merge with
71+
/// \param widen_mode: Indicates if this is a widening merge
7172
///
7273
/// \return Returns the result of the merge
73-
abstract_object_pointert
74-
merge(const abstract_object_pointert &other) const override;
74+
abstract_object_pointert merge(
75+
const abstract_object_pointert &other,
76+
const wident &widen_mode) const override;
7577
abstract_object_pointert
7678
meet(const abstract_object_pointert &other) const override;
7779

7880
private:
7981
/// Merges another abstract value into this one
8082
///
8183
/// \param other: the abstract object to merge with
84+
/// \param widen_mode: Indicates if this is a widening merge
8285
///
8386
/// \return Returns a new abstract object that is the result of the merge
8487
/// unless the merge is the same as this abstract object, in which
8588
/// case it returns this.
86-
abstract_object_pointert
87-
merge_with_value(const abstract_value_pointert &other) const;
89+
abstract_object_pointert merge_with_value(
90+
const abstract_value_pointert &other,
91+
const wident &widen_mode) const;
8892
abstract_object_pointert
8993
meet_with_value(const abstract_value_pointert &other) const;
9094

src/analyses/variable-sensitivity/constant_pointer_abstract_object.cpp

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -57,43 +57,32 @@ constant_pointer_abstract_objectt::constant_pointer_abstract_objectt(
5757
}
5858

5959
abstract_object_pointert constant_pointer_abstract_objectt::merge(
60-
const abstract_object_pointert &other) const
60+
const abstract_object_pointert &other,
61+
const wident &widen_mode) const
6162
{
6263
auto cast_other =
6364
std::dynamic_pointer_cast<const constant_pointer_abstract_objectt>(other);
6465
if(cast_other)
65-
{
66-
return merge_constant_pointers(cast_other);
67-
}
68-
else
69-
{
70-
// TODO(tkiley): How do we set the result to be toppish?
71-
return abstract_pointer_objectt::merge(other);
72-
}
66+
return merge_constant_pointers(cast_other, widen_mode);
67+
68+
return abstract_pointer_objectt::merge(other, widen_mode);
7369
}
7470

7571
abstract_object_pointert
7672
constant_pointer_abstract_objectt::merge_constant_pointers(
77-
const constant_pointer_abstract_pointert &other) const
73+
const constant_pointer_abstract_pointert &other,
74+
const wident &widen_mode) const
7875
{
7976
if(is_bottom())
80-
{
8177
return std::make_shared<constant_pointer_abstract_objectt>(*other);
82-
}
83-
else
84-
{
85-
bool matching_pointer =
86-
value_stack.to_expression() == other->value_stack.to_expression();
8778

88-
if(matching_pointer)
89-
{
90-
return shared_from_this();
91-
}
92-
else
93-
{
94-
return abstract_pointer_objectt::merge(other);
95-
}
96-
}
79+
bool matching_pointers =
80+
value_stack.to_expression() == other->value_stack.to_expression();
81+
82+
if(matching_pointers)
83+
return shared_from_this();
84+
85+
return abstract_pointer_objectt::merge(other, widen_mode);
9786
}
9887

9988
exprt constant_pointer_abstract_objectt::to_constant() const
@@ -196,7 +185,7 @@ abstract_object_pointert constant_pointer_abstract_objectt::write_dereference(
196185
{
197186
abstract_object_pointert pointed_value = environment.eval(value, ns);
198187
abstract_object_pointert merged_value =
199-
abstract_objectt::merge(pointed_value, new_value).object;
188+
abstract_objectt::merge(pointed_value, new_value, wident::no).object;
200189
environment.assign(value, merged_value, ns);
201190
}
202191
else

src/analyses/variable-sensitivity/constant_pointer_abstract_object.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,12 @@ class constant_pointer_abstract_objectt : public abstract_pointer_objectt
119119
/// constant pointer merge
120120
///
121121
/// \param op1: the pointer being merged
122+
/// \param widen_mode: Indicates if this is a widening merge
122123
///
123124
/// \return Returns the result of the merge.
124-
abstract_object_pointert
125-
merge(const abstract_object_pointert &op1) const override;
125+
abstract_object_pointert merge(
126+
const abstract_object_pointert &op1,
127+
const wident &widen_mode) const override;
126128

127129
CLONE
128130

@@ -131,12 +133,14 @@ class constant_pointer_abstract_objectt : public abstract_pointer_objectt
131133
/// value, we merge, otherwise we set to top.
132134
///
133135
/// \param other: the pointer being merged
136+
/// \param widen_mode: Indicates if this is a widening merge
134137
///
135138
/// \return Returns a new abstract object that is the result of the merge
136139
/// unless the merge is the same as this abstract object, in which
137140
/// case it returns this.
138141
abstract_object_pointert merge_constant_pointers(
139-
const constant_pointer_abstract_pointert &other) const;
142+
const constant_pointer_abstract_pointert &other,
143+
const wident &widen_mode) const;
140144

141145
write_stackt value_stack;
142146
};

src/analyses/variable-sensitivity/data_dependency_context.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,14 @@ abstract_object_pointert data_dependency_contextt::update_location_context(
230230
* object with a given abstract_object
231231
*
232232
* \param other the abstract object to merge with
233+
* \param widen_mode: Indicates if this is a widening merge
233234
*
234235
* \return the result of the merge, or 'this' if the merge would not change
235236
* the current abstract object
236237
*/
237-
abstract_object_pointert
238-
data_dependency_contextt::merge(const abstract_object_pointert &other) const
238+
abstract_object_pointert data_dependency_contextt::merge(
239+
const abstract_object_pointert &other,
240+
const wident &widen_mode) const
239241
{
240242
auto cast_other =
241243
std::dynamic_pointer_cast<const data_dependency_contextt>(other);
@@ -244,7 +246,7 @@ data_dependency_contextt::merge(const abstract_object_pointert &other) const
244246
{
245247
const auto merged_parent =
246248
std::dynamic_pointer_cast<const data_dependency_contextt>(
247-
this->write_location_contextt::merge(other));
249+
this->write_location_contextt::merge(other, widen_mode));
248250

249251
const auto updated_parent =
250252
std::dynamic_pointer_cast<const data_dependency_contextt>(
@@ -275,7 +277,7 @@ data_dependency_contextt::merge(const abstract_object_pointert &other) const
275277
return shared_from_this();
276278
}
277279

278-
return abstract_objectt::merge(other);
280+
return abstract_objectt::merge(other, widen_mode);
279281
}
280282

281283
/**

src/analyses/variable-sensitivity/data_dependency_context.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ class data_dependency_contextt : public write_location_contextt
7070
protected:
7171
CLONE
7272

73-
abstract_object_pointert
74-
merge(const abstract_object_pointert &other) const override;
73+
abstract_object_pointert merge(
74+
const abstract_object_pointert &other,
75+
const wident &widen_mode) const override;
7576

7677
abstract_object_pointert abstract_object_merge_internal(
7778
const abstract_object_pointert &other) const override;

0 commit comments

Comments
 (0)