Skip to content

Commit 104ba11

Browse files
authored
Merge pull request #5887 from jezhiggins/vsd-value-sets-and-intervals
VSD - Further cross-representation expression evaluation
2 parents 526ea61 + b86dbcf commit 104ba11

File tree

13 files changed

+1052
-357
lines changed

13 files changed

+1052
-357
lines changed

src/analyses/variable-sensitivity/abstract_value_object.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,9 @@ bool any_of_type(const std::vector<abstract_object_pointert> &operands)
135135
operands.begin(),
136136
operands.end(),
137137
[](const abstract_object_pointert &p) {
138-
return std::dynamic_pointer_cast<const representation_type>(p) !=
139-
nullptr;
138+
return (!p->is_top()) &&
139+
(std::dynamic_pointer_cast<const representation_type>(p) !=
140+
nullptr);
140141
}) != operands.end();
141142
}
142143

@@ -555,13 +556,25 @@ class value_set_evaluator
555556
rewrite_expression(const std::vector<abstract_object_pointert> &ops) const
556557
{
557558
auto operands_expr = exprt::operandst{};
558-
for(auto v : ops)
559-
operands_expr.push_back(v->to_constant());
559+
for(size_t i = 0; i != expression.operands().size(); ++i)
560+
{
561+
const auto &v = ops[i];
562+
if(is_constant_value(v))
563+
operands_expr.push_back(v->to_constant());
564+
else
565+
operands_expr.push_back(expression.operands()[i]);
566+
}
560567
auto rewritten_expr =
561568
exprt(expression.id(), expression.type(), std::move(operands_expr));
562569
return rewritten_expr;
563570
}
564571

572+
static bool is_constant_value(const abstract_object_pointert &v)
573+
{
574+
return std::dynamic_pointer_cast<const constant_abstract_valuet>(v) !=
575+
nullptr;
576+
}
577+
565578
std::vector<value_ranget> operands_as_ranges() const
566579
{
567580
auto unwrapped = std::vector<value_ranget>{};

src/analyses/variable-sensitivity/abstract_value_object.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,8 @@ class abstract_value_objectt : public abstract_objectt,
287287
virtual index_range_implementation_ptrt
288288
index_range_implementation(const namespacet &ns) const = 0;
289289

290-
virtual value_range_implementation_ptrt value_range_implementation() const
291-
{
292-
return util_make_unique<empty_value_ranget>();
293-
}
290+
virtual value_range_implementation_ptrt
291+
value_range_implementation() const = 0;
294292
};
295293

296294
#endif

src/analyses/variable-sensitivity/interval_abstract_value.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,12 @@ interval_abstract_valuet::index_range_implementation(const namespacet &ns) const
427427
return make_interval_index_range(interval, ns);
428428
}
429429

430+
value_range_implementation_ptrt
431+
interval_abstract_valuet::value_range_implementation() const
432+
{
433+
return make_single_value_range(shared_from_this());
434+
}
435+
430436
void interval_abstract_valuet::get_statistics(
431437
abstract_object_statisticst &statistics,
432438
abstract_object_visitedt &visited,

src/analyses/variable-sensitivity/interval_abstract_value.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class interval_abstract_valuet : public abstract_value_objectt
3838
index_range_implementation_ptrt
3939
index_range_implementation(const namespacet &ns) const override;
4040

41+
value_range_implementation_ptrt value_range_implementation() const override;
42+
4143
exprt to_constant() const override;
4244
const constant_interval_exprt &to_interval() const
4345
{

src/analyses/variable-sensitivity/value_set_abstract_object.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,17 @@
1111

1212
#include <analyses/variable-sensitivity/constant_abstract_value.h>
1313
#include <analyses/variable-sensitivity/context_abstract_object.h>
14-
#include <analyses/variable-sensitivity/interval_abstract_value.h>
1514
#include <analyses/variable-sensitivity/two_value_array_abstract_object.h>
1615
#include <analyses/variable-sensitivity/value_set_abstract_object.h>
1716
#include <util/make_unique.h>
1817

1918
static index_range_implementation_ptrt
20-
make_value_set_index_range(const abstract_object_sett &vals);
19+
make_value_set_index_range(const std::set<exprt> &vals);
2120

2221
class value_set_index_ranget : public index_range_implementationt
2322
{
2423
public:
25-
explicit value_set_index_ranget(const abstract_object_sett &vals)
24+
explicit value_set_index_ranget(const std::set<exprt> &vals)
2625
: values(vals), cur(), next(values.begin())
2726
{
2827
PRECONDITION(!values.empty());
@@ -37,7 +36,7 @@ class value_set_index_ranget : public index_range_implementationt
3736
if(next == values.end())
3837
return false;
3938

40-
cur = (*next)->to_constant();
39+
cur = *next;
4140
++next;
4241
return true;
4342
}
@@ -47,13 +46,13 @@ class value_set_index_ranget : public index_range_implementationt
4746
}
4847

4948
private:
50-
const abstract_object_sett &values;
49+
std::set<exprt> values;
5150
exprt cur;
52-
abstract_object_sett::const_iterator next;
51+
std::set<exprt>::const_iterator next;
5352
};
5453

5554
static index_range_implementation_ptrt
56-
make_value_set_index_range(const abstract_object_sett &vals)
55+
make_value_set_index_range(const std::set<exprt> &vals)
5756
{
5857
return util_make_unique<value_set_index_ranget>(vals);
5958
}
@@ -146,7 +145,15 @@ value_set_abstract_objectt::index_range_implementation(
146145
if(values.empty())
147146
return make_indeterminate_index_range();
148147

149-
return make_value_set_index_range(values);
148+
std::set<exprt> flattened;
149+
for(const auto &o : values)
150+
{
151+
const auto &v = std::dynamic_pointer_cast<const abstract_value_objectt>(o);
152+
for(auto e : v->index_range(ns))
153+
flattened.insert(e);
154+
}
155+
156+
return make_value_set_index_range(flattened);
150157
}
151158

152159
value_range_implementation_ptrt

unit/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@ SRC += analyses/ai/ai.cpp \
1616
analyses/does_remove_const/is_type_at_least_as_const_as.cpp \
1717
analyses/variable-sensitivity/abstract_object/merge.cpp \
1818
analyses/variable-sensitivity/abstract_object/index_range.cpp \
19-
analyses/variable-sensitivity/constant_abstract_value/expression_evaluation.cpp \
2019
analyses/variable-sensitivity/constant_abstract_value/merge.cpp \
2120
analyses/variable-sensitivity/full_array_abstract_object/merge.cpp \
2221
analyses/variable-sensitivity/eval.cpp \
2322
analyses/variable-sensitivity/eval-member-access.cpp \
2423
analyses/variable-sensitivity/interval_abstract_value/meet.cpp \
2524
analyses/variable-sensitivity/full_struct_abstract_object/merge.cpp \
2625
analyses/variable-sensitivity/last_written_location.cpp \
26+
analyses/variable-sensitivity/value_expression_evaluation/expression_evaluation.cpp \
2727
analyses/variable-sensitivity/value_set/abstract_value.cpp \
28-
analyses/variable-sensitivity/value_set_abstract_object/expression_evaluation.cpp \
2928
analyses/variable-sensitivity/value_set_abstract_object/merge.cpp \
3029
analyses/variable-sensitivity/variable_sensitivity_test_helpers.cpp \
3130
ansi-c/max_malloc_size.cpp \

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

Lines changed: 103 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1+
#include "analyses/variable-sensitivity/variable_sensitivity_test_helpers.h"
12
#include <analyses/variable-sensitivity/abstract_environment.h>
2-
#include <analyses/variable-sensitivity/abstract_object.h>
33
#include <analyses/variable-sensitivity/constant_abstract_value.h>
44
#include <analyses/variable-sensitivity/value_set_abstract_object.h>
55
#include <analyses/variable-sensitivity/variable_sensitivity_object_factory.h>
66
#include <testing-utils/use_catch.h>
77
#include <util/arith_tools.h>
8-
#include <util/mathematical_types.h>
98
#include <util/namespace.h>
109
#include <util/symbol_table.h>
1110

1211
SCENARIO(
1312
"index_range for constant_abstract_values"
14-
"[core][analyses][variable-sensitivity][constant_abstract_value][index-"
13+
"[core][analyses][variable-sensitivity][constant_abstract_value][index_"
1514
"range]")
1615
{
1716
auto type = signedbv_typet(32);
@@ -26,8 +25,7 @@ SCENARIO(
2625
{
2726
auto int_value = 99;
2827
auto value_expr = from_integer(int_value, type);
29-
auto value =
30-
std::make_shared<constant_abstract_valuet>(value_expr, env, ns);
28+
auto value = make_constant(value_expr, env, ns);
3129

3230
auto range = value->index_range(ns);
3331

@@ -59,7 +57,7 @@ SCENARIO(
5957

6058
GIVEN("a top constant's range is has a single nil expression")
6159
{
62-
auto value = std::make_shared<constant_abstract_valuet>(type);
60+
auto value = make_top_constant();
6361

6462
auto range = value->index_range(ns);
6563

@@ -78,7 +76,7 @@ SCENARIO(
7876

7977
SCENARIO(
8078
"index_range for interval_abstract_values"
81-
"[core][analyses][variable-sensitivity][interval_abstract_value][index-"
79+
"[core][analyses][variable-sensitivity][interval_abstract_value][index_"
8280
"range]")
8381
{
8482
auto object_factory = variable_sensitivity_object_factoryt::configured_with(
@@ -91,7 +89,7 @@ SCENARIO(
9189

9290
GIVEN("a top intervals's range is empty")
9391
{
94-
auto value = std::make_shared<interval_abstract_valuet>(type, true, false);
92+
auto value = make_top_interval();
9593

9694
auto range = value->index_range(ns);
9795

@@ -105,8 +103,7 @@ SCENARIO(
105103
{
106104
auto int_value = 99;
107105
auto value_expr = from_integer(int_value, type);
108-
auto value =
109-
std::make_shared<interval_abstract_valuet>(value_expr, env, ns);
106+
auto value = make_interval(value_expr, value_expr, env, ns);
110107

111108
auto range = value->index_range(ns);
112109

@@ -127,12 +124,9 @@ SCENARIO(
127124
GIVEN("a [99,100] interval's index_range has two elements")
128125
{
129126
auto int_value = 99;
130-
auto value_expr = from_integer(int_value, type);
131-
auto value = std::make_shared<interval_abstract_valuet>(
132-
constant_interval_exprt(
133-
from_integer(int_value, type), from_integer(int_value + 1, type), type),
134-
env,
135-
ns);
127+
auto lower = from_integer(int_value, type);
128+
auto upper = from_integer(int_value + 1, type);
129+
auto value = make_interval(lower, upper, env, ns);
136130

137131
auto range = value->index_range(ns);
138132

@@ -159,12 +153,9 @@ SCENARIO(
159153
GIVEN("a [99,102] interval's index_range has four elements")
160154
{
161155
auto int_value = 99;
162-
auto value_expr = from_integer(int_value, type);
163-
auto value = std::make_shared<interval_abstract_valuet>(
164-
constant_interval_exprt(
165-
from_integer(int_value, type), from_integer(int_value + 3, type), type),
166-
env,
167-
ns);
156+
auto lower = from_integer(int_value, type);
157+
auto upper = from_integer(int_value + 3, type);
158+
auto value = make_interval(lower, upper, env, ns);
168159

169160
auto range = value->index_range(ns);
170161

@@ -186,7 +177,7 @@ SCENARIO(
186177

187178
SCENARIO(
188179
"index_range for value_set_abstract_values"
189-
"[core][analyses][variable-sensitivity][value_set_abstract_value][index-"
180+
"[core][analyses][variable-sensitivity][value_set_abstract_value][index_"
190181
"range]")
191182
{
192183
auto object_factory = variable_sensitivity_object_factoryt::configured_with(
@@ -197,10 +188,9 @@ SCENARIO(
197188
namespacet ns(symbol_table);
198189
auto type = signedbv_typet(32);
199190

200-
GIVEN("a value_set is empty")
191+
GIVEN("a TOP value_set is empty")
201192
{
202-
auto value =
203-
std::make_shared<value_set_abstract_objectt>(type, true, false);
193+
auto value = make_top_value_set();
204194
auto range = value->index_range(ns);
205195

206196
THEN("range should have a nil expr")
@@ -214,4 +204,91 @@ SCENARIO(
214204
REQUIRE(i == range.end());
215205
}
216206
}
207+
GIVEN("a value_set { 99, 100, 101, 102 } index_range has four elements")
208+
{
209+
auto int_value = 99;
210+
auto _99 = from_integer(int_value, type);
211+
auto _100 = from_integer(100, type);
212+
auto _101 = from_integer(101, type);
213+
auto _102 = from_integer(102, type);
214+
auto value = make_value_set({_99, _100, _101, _102}, env, ns);
215+
216+
auto range = value->index_range(ns);
217+
218+
THEN("range has four values")
219+
{
220+
auto values = std::vector<exprt>();
221+
for(const auto &e : range)
222+
values.push_back(to_constant_expr(e));
223+
224+
REQUIRE(values.size() == 4);
225+
EXPECT(values, {_99, _100, _101, _102});
226+
}
227+
}
228+
GIVEN("a value_set { [99, 102] } index_range has four elements")
229+
{
230+
auto int_value = 99;
231+
auto _99 = from_integer(int_value, type);
232+
auto _100 = from_integer(100, type);
233+
auto _101 = from_integer(101, type);
234+
auto _102 = from_integer(102, type);
235+
auto _99_102 = constant_interval_exprt(_99, _102);
236+
auto value = make_value_set({_99_102}, env, ns);
237+
238+
auto range = value->index_range(ns);
239+
240+
THEN("range has four values")
241+
{
242+
auto values = std::vector<exprt>();
243+
for(const auto &e : range)
244+
values.push_back(to_constant_expr(e));
245+
246+
REQUIRE(values.size() == 4);
247+
EXPECT(values, {_99, _100, _101, _102});
248+
}
249+
}
250+
GIVEN("a value_set { 99, 100, [101, 102] } index_range has four elements")
251+
{
252+
auto int_value = 99;
253+
auto _99 = from_integer(int_value, type);
254+
auto _100 = from_integer(100, type);
255+
auto _101 = from_integer(101, type);
256+
auto _102 = from_integer(102, type);
257+
auto _101_102 = constant_interval_exprt(_101, _102);
258+
auto value = make_value_set({_99, _101_102, _100}, env, ns);
259+
260+
auto range = value->index_range(ns);
261+
262+
THEN("range has four values")
263+
{
264+
auto values = std::vector<exprt>();
265+
for(const auto &e : range)
266+
values.push_back(to_constant_expr(e));
267+
268+
REQUIRE(values.size() == 4);
269+
EXPECT(values, {_99, _100, _101, _102});
270+
}
271+
}
272+
GIVEN("a value_set { [99, 102], 100, 101 } index_range has four elements")
273+
{
274+
auto int_value = 99;
275+
auto _99 = from_integer(int_value, type);
276+
auto _100 = from_integer(100, type);
277+
auto _101 = from_integer(101, type);
278+
auto _102 = from_integer(102, type);
279+
auto _99_102 = constant_interval_exprt(_99, _102);
280+
auto value = make_value_set({_99_102, _100, _101}, env, ns);
281+
282+
auto range = value->index_range(ns);
283+
284+
THEN("range has four values")
285+
{
286+
auto values = std::vector<exprt>();
287+
for(const auto &e : range)
288+
values.push_back(to_constant_expr(e));
289+
290+
REQUIRE(values.size() == 4);
291+
EXPECT(values, {_99, _100, _101, _102});
292+
}
293+
}
217294
}

0 commit comments

Comments
 (0)