Skip to content

Commit 0b70b2e

Browse files
committed
Intervals [FALSE, TRUE] go to top.
Intervals with range [min(type), max(type)] go top. However, by extension [FALSE, TRUE] should also go top. This change extends the TOP check constructing interval_abstract_values to cover intervals of type bool and c_bool.
1 parent 5b8e8fa commit 0b70b2e

File tree

5 files changed

+99
-2
lines changed

5 files changed

+99
-2
lines changed

regression/goto-analyzer/ternary-operator/test-intervals.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ main.c
55
^SIGNAL=0$
66
main::1::b1 \(\) -> \[1, 1\] @ \[2\]
77
main::1::b2 \(\) -> \[0, 0\] @ \[3\]
8-
main::1::b3 \(\) -> \[0, 1\] @ \[5\]
8+
main::1::b3 \(\) -> TOP @ \[5\]
99
main::1::i \(\) -> \[A, A\] @ \[7\]
1010
main::1::j \(\) -> \[14, 14\] @ \[9\]
1111
main::1::k \(\) -> \[A, 14\] @ \[11\]

src/analyses/variable-sensitivity/interval_abstract_value.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,25 @@ interval_abstract_valuet::interval_abstract_valuet(
244244
{
245245
}
246246

247+
bool new_interval_is_top(const constant_interval_exprt &e)
248+
{
249+
if(e.is_top())
250+
return true;
251+
252+
if(e.get_lower().is_false() && e.get_upper().is_true())
253+
return true;
254+
if(
255+
e.type().id() == ID_c_bool && e.get_lower().is_zero() &&
256+
e.get_upper().is_one())
257+
return true;
258+
259+
return false;
260+
}
261+
247262
interval_abstract_valuet::interval_abstract_valuet(
248263
const constant_interval_exprt &e)
249-
: abstract_value_objectt(e.type(), e.is_top(), e.is_bottom()), interval(e)
264+
: abstract_value_objectt(e.type(), new_interval_is_top(e), e.is_bottom()),
265+
interval(e)
250266
{
251267
}
252268

@@ -290,6 +306,11 @@ exprt interval_abstract_valuet::to_constant() const
290306
#endif
291307
}
292308

309+
void interval_abstract_valuet::set_top_internal()
310+
{
311+
interval = constant_interval_exprt(type());
312+
}
313+
293314
size_t interval_abstract_valuet::internal_hash() const
294315
{
295316
return std::hash<std::string>{}(interval.pretty());

src/analyses/variable-sensitivity/interval_abstract_value.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class interval_abstract_valuet : public abstract_value_objectt
9696

9797
private:
9898
constant_interval_exprt interval;
99+
100+
void set_top_internal() override;
99101
};
100102

101103
#endif // CPROVER_ANALYSES_VARIABLE_SENSITIVITY_INTERVAL_ABSTRACT_VALUE_H

unit/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SRC += analyses/ai/ai.cpp \
2121
analyses/variable-sensitivity/full_array_abstract_object/merge.cpp \
2222
analyses/variable-sensitivity/eval.cpp \
2323
analyses/variable-sensitivity/eval-member-access.cpp \
24+
analyses/variable-sensitivity/interval_abstract_value/extremes-go-top.cpp \
2425
analyses/variable-sensitivity/interval_abstract_value/meet.cpp \
2526
analyses/variable-sensitivity/interval_abstract_value/merge.cpp \
2627
analyses/variable-sensitivity/interval_abstract_value/widening_merge.cpp \
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for interval_abstract_valuet
4+
5+
Author: Jez Higgins
6+
7+
\*******************************************************************/
8+
9+
#include <analyses/variable-sensitivity/abstract_environment.h>
10+
#include <analyses/variable-sensitivity/abstract_object.h>
11+
#include <analyses/variable-sensitivity/interval_abstract_value.h>
12+
#include <analyses/variable-sensitivity/variable_sensitivity_object_factory.h>
13+
#include <testing-utils/use_catch.h>
14+
15+
#include <analyses/variable-sensitivity/variable_sensitivity_test_helpers.h>
16+
#include <util/arith_tools.h>
17+
#include <util/bitvector_types.h>
18+
19+
static void
20+
verify_extreme_interval(typet type, abstract_environmentt &env, namespacet &ns)
21+
{
22+
auto interval = make_interval(min_exprt(type), max_exprt(type), env, ns);
23+
24+
EXPECT_TOP(interval);
25+
}
26+
27+
SCENARIO(
28+
"extreme intervals go TOP",
29+
"[core][analyses][variable-sensitivity][interval_abstract_value][extreme]")
30+
{
31+
auto object_factory = variable_sensitivity_object_factoryt::configured_with(
32+
vsd_configt::intervals());
33+
34+
auto environment = abstract_environmentt{object_factory};
35+
environment.make_top();
36+
auto symbol_table = symbol_tablet{};
37+
auto ns = namespacet{symbol_table};
38+
39+
GIVEN("[min-max] signed goes TOP")
40+
{
41+
verify_extreme_interval(signedbv_typet(32), environment, ns);
42+
}
43+
GIVEN("[min-max] unsigned goes TOP")
44+
{
45+
verify_extreme_interval(unsignedbv_typet(32), environment, ns);
46+
}
47+
GIVEN("[min-max] bool goes TOP")
48+
{
49+
verify_extreme_interval(bool_typet(), environment, ns);
50+
}
51+
GIVEN("[min-max] c_bool goes TOP")
52+
{
53+
verify_extreme_interval(bitvector_typet(ID_c_bool, 8), environment, ns);
54+
}
55+
GIVEN("[FALSE, TRUE] goes TOP")
56+
{
57+
auto boolInterval =
58+
make_interval(false_exprt(), true_exprt(), environment, ns);
59+
60+
EXPECT_TOP(boolInterval);
61+
}
62+
GIVEN("[0, 1] c_bool goes TOP")
63+
{
64+
auto c_bool_type = bitvector_typet(ID_c_bool, 8);
65+
auto boolInterval = make_interval(
66+
from_integer(0, c_bool_type),
67+
from_integer(1, c_bool_type),
68+
environment,
69+
ns);
70+
71+
EXPECT_TOP(boolInterval);
72+
}
73+
}

0 commit comments

Comments
 (0)