Skip to content

Commit d4d976a

Browse files
author
thk123
committed
Added unit tests to validate the return meaning of ai_simplify_lhs
These tests use a mock implementation of the `ai_domain_baset` interface just to validate that true means no simplification.
1 parent 64ab723 commit d4d976a

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SRC = src/expr/require_expr.cpp \
77

88
# Test source files
99
SRC += unit_tests.cpp \
10+
analyses/ai/ai_simplify_lhs.cpp \
1011
analyses/does_remove_const/does_expr_lose_const.cpp \
1112
analyses/does_remove_const/does_type_preserve_const_correctness.cpp \
1213
analyses/does_remove_const/is_type_at_least_as_const_as.cpp \

unit/analyses/ai/ai_simplify_lhs.cpp

+168
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for ai_domain_baset::ai_simplify_lhs
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Unit tests for ai_domain_baset::ai_simplify_lhs
11+
12+
#include <catch.hpp>
13+
14+
#include <analyses/ai.h>
15+
16+
#include <ansi-c/ansi_c_language.h>
17+
18+
#include <util/arith_tools.h>
19+
#include <util/config.h>
20+
#include <util/namespace.h>
21+
#include <util/ui_message.h>
22+
#include <util/simplify_expr.h>
23+
24+
class constant_simplification_mockt:public ai_domain_baset
25+
{
26+
public:
27+
void transform(locationt, locationt, ai_baset &, const namespacet &) override
28+
{}
29+
void make_bottom() override
30+
{}
31+
void make_top() override
32+
{}
33+
void make_entry() override
34+
{}
35+
36+
bool ai_simplify(exprt &condition, const namespacet &ns) const override;
37+
};
38+
39+
bool constant_simplification_mockt::ai_simplify(
40+
exprt &condition, const namespacet &ns) const
41+
{
42+
exprt simplified_expr=simplify_expr(condition, ns);
43+
// no simplification
44+
if(simplified_expr==condition)
45+
{
46+
return true;
47+
}
48+
// a simplification has occurred
49+
condition=simplified_expr;
50+
return false;
51+
}
52+
53+
SCENARIO("ai_domain_baset::ai_simplify_lhs",
54+
"[core][analyses][ai][ai_simplify_lhs]")
55+
{
56+
ui_message_handlert message_handler;
57+
ansi_c_languaget language;
58+
language.set_message_handler(message_handler);
59+
60+
symbol_tablet symbol_table;
61+
namespacet ns(symbol_table);
62+
63+
constant_simplification_mockt mock_ai_domain;
64+
65+
config.set_arch("none");
66+
67+
GIVEN("A index_exprt")
68+
{
69+
// Construct an expression that the simplify_expr can simplify
70+
exprt simplifiable_expression;
71+
bool compile_failed=
72+
language.to_expr("1 + 1", "", simplifiable_expression, ns);
73+
74+
const unsigned int array_size=5;
75+
array_typet array_type(
76+
signedbv_typet(32), constant_exprt::integer_constant(array_size));
77+
78+
// Verify the results of the setup
79+
REQUIRE_FALSE(compile_failed);\
80+
REQUIRE(simplifiable_expression.id()==ID_plus);
81+
exprt simplified_version=simplify_expr(simplifiable_expression, ns);
82+
REQUIRE(simplified_version.id()==ID_constant);
83+
84+
WHEN(
85+
"Simplifying an index expression with constant index but variable array")
86+
{
87+
const index_exprt &index_expr=
88+
index_exprt(symbol_exprt("a", array_type), simplifiable_expression);
89+
90+
THEN("Then only the index of the part of the expression should be "
91+
"simplified")
92+
{
93+
exprt out_expr=index_expr;
94+
bool no_simplification=mock_ai_domain.ai_simplify_lhs(out_expr, ns);
95+
REQUIRE_FALSE(no_simplification);
96+
REQUIRE(index_expr.id()==ID_index);
97+
98+
index_exprt simplified_index_expr=to_index_expr(out_expr);
99+
REQUIRE(simplified_index_expr.index().id()==ID_constant);
100+
101+
constant_exprt constant_index=
102+
to_constant_expr(simplified_index_expr.index());
103+
104+
mp_integer out_index;
105+
bool failed_to_integer=to_integer(constant_index, out_index);
106+
REQUIRE_FALSE(failed_to_integer);
107+
REQUIRE(out_index==2);
108+
}
109+
}
110+
WHEN("Simplifying an index expression with variable index and array")
111+
{
112+
// a[i]
113+
const index_exprt &index_expr=
114+
index_exprt(
115+
symbol_exprt("a", array_type), symbol_exprt("i", signedbv_typet(32)));
116+
117+
THEN("Then no simplification should occur")
118+
{
119+
exprt out_expr=index_expr;
120+
bool no_simplification=mock_ai_domain.ai_simplify_lhs(out_expr, ns);
121+
REQUIRE(no_simplification);
122+
REQUIRE(index_expr.id()==ID_index);
123+
124+
index_exprt simplified_index_expr=to_index_expr(out_expr);
125+
REQUIRE(simplified_index_expr.index().id()==ID_symbol);
126+
}
127+
}
128+
129+
// This fails since the implementation does do a constant simplification
130+
// on the array part. It isn't clear to me if this is correct
131+
#if 0
132+
WHEN(
133+
"Simplifying an index expression with constant index in a constant array")
134+
{
135+
array_exprt constant_array=array_exprt(array_type);
136+
for(unsigned int i=0; i<array_size; ++i)
137+
{
138+
REQUIRE(constant_array.operands().size()==i);
139+
constant_array.operands().push_back(
140+
constant_exprt::integer_constant(i));
141+
}
142+
143+
const index_exprt &index_expr=
144+
index_exprt(constant_array, simplifiable_expression);
145+
146+
THEN("Then only the index of the part of the expression should be "
147+
"simplified")
148+
{
149+
exprt out_expr=index_expr;
150+
bool no_simplification=mock_ai_domain.ai_simplify_lhs(out_expr, ns);
151+
REQUIRE_FALSE(no_simplification);
152+
REQUIRE(out_expr.id()==ID_index);
153+
154+
index_exprt simplified_index_expr=to_index_expr(out_expr);
155+
REQUIRE(simplified_index_expr.index().id()==ID_constant);
156+
157+
constant_exprt constant_index=
158+
to_constant_expr(simplified_index_expr.index());
159+
160+
mp_integer out_index;
161+
bool failed_to_integer=to_integer(constant_index, out_index);
162+
REQUIRE_FALSE(failed_to_integer);
163+
REQUIRE(out_index==2);
164+
}
165+
}
166+
#endif
167+
}
168+
}

0 commit comments

Comments
 (0)